Interval inside React useEffect - store it in a useRef Hook to preserve value overtime warning
Asked Answered
K

2

11

So I have this method:

useEffect(() => {
    //.. other logic here

    // Firefox doesn't support looping video, so we emulate it this way
    video.addEventListener(
      "ended",
      function() {
        video.play();
      },
      false
    );
  }, [videoWidth, videoHeight]);

Now it throws an error where it says:

Assignments to the 'interval' variable from inside React Hook useEffect will be lost after each render. To preserve the value over time, store it in a useRef Hook and keep the mutable value in the '.current' property. Otherwise, you can move this variable directly inside useEffect.

I am confused on what does this mean? especially this part: To preserve the value over time, store it in a useRef Hook and keep the mutable value in the '.current' property.

Kirby answered 17/7, 2019 at 21:11 Comment(1)
Can you put the whole code of your component, it would be great to help you to resolve the error.Cue
T
10

The error is pointing you to the right direction. Use the useRef hook to reference the video element. Since the handleVideo function makes the dependencies of useEffect Hook change on every render we wrap the handleVideo definition into its own useCallback() Hook.

import React, { useEffect, useRef, useCallback } from "react";

function Video() {
  const videoRef = useRef(null);

  const handleVideo = useCallback(() => {
    videoRef.current.play()
  }, [])

  useEffect(() => {
    const video = videoRef.current
    video.addEventListener('ended', handleVideo)

    return () => {
      video.removeEventListener('ended', handleVideo)
    }
  }, [handleVideo])



  return <video width="400" controls ref={videoRef} src="https://www.w3schools.com/html/mov_bbb.mp4" />
}
Transcend answered 17/7, 2019 at 22:28 Comment(0)
F
0

try this way it will be work

const video = useRef(null);
const videoPlay = () => { //just hate stateFull Function
        video.current.play();
      }
useEffect(() => {
    //.. other logic here

    // Firefox doesn't support looping video, so we emulate it this way
    video.addEventListener(
      "ended",
      videoPlay,
      false
    );
    return video.removeEventListener("ended", videoPlay, true)
  }, [videoWidth, videoHeight, video]);
   <video ref={video}>
      <source src={src} type="video/mp4" />
   </video>

if put the code in jsfiddle or some whare like this we can help you more

Folkrock answered 17/7, 2019 at 22:16 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.