skip to Main Content

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


  1. Chosen as BEST ANSWER

    Not sure which props are changing, but I had to specifically add a custom checker in the memo function:

    const PlayerMemo = memo(Player, (prev, next) => {
      return prev.video.id === next.video.id;
    });
    

  2. On each render new onTimeUpdate callback is created. Functions are compared by reference and it gets a new one on each render. You can use useCallback 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.

    onTimeUpdate={useCallback(cb_here, dependencies_here)}
    

    With your ref implementation, dependencies could be just an empty array

    onTimeUpdate={useCallback(cb_here, [])}
    
    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search