I have the following code:
function Player({
videlEl,
onTimeUpdate = () => {},
}: {
videlEl: React.RefObject<HTMLVideoElement>;
onTimeUpdate: () => void;
}) {
const { file } = useVideoCreateStore();
if (!file) return null;
return (
<video
ref={videlEl}
src={URL.createObjectURL(file)}
controls
onTimeUpdate={onTimeUpdate}
/>
);
}
const PlayerMemo = memo(Player);
export default function VideoEdit({ video }: VideoEditProps) {
const id = video.id;
const videoHeight = video.height;
const videoWidth = video.width;
const [playTime, setPlayTime] = useState(0);
const videoEl = useRef<HTMLVideoElement>(null);
return (
<>
<div className="relative border rounded-sm">
<PlayerMemo
videlEl={videoEl}
onTimeUpdate={() => {
const time = videoEl.current?.currentTime;
console.log(videoEl);
if (!time) {
return;
}
setPlayTime(time);
console.log(videoEl.current?.currentTime);
}}
/>
</div>
<Button
onClick={() => {
capture2();
}}
>
Capture
</Button>
</>
);
}
Because of the setState
in the onTimeUpdate
function, the component re-renders the <video>
on playback, and the video restarts again.
I’ve tried passing in a useRef
as well as React.memo
(see code), but nothing is stopping the re-render from happening.
2
Answers
Not sure which props are changing, but I had to specifically add a custom checker in the
memo
function:On each render new
onTimeUpdate
callback is created. Functions are compared by reference and it gets a new one on each render. You can useuseCallback
there. It does not prevent recreating of the callback among the renders, but it keeps one of the references to it until one of the dependencies change.With your
ref
implementation, dependencies could be just an empty array