Home > Enterprise >  API is getting called inside useEffet multiple times (React js)
API is getting called inside useEffet multiple times (React js)

Time:12-18

I am calling an function inside useEffect but it is rendering multiple times.


let courseVideo = async () => {
    
    const response = await api
      .post(COURSE_VDO_URL, JSON.stringify({ courseID, username }), {
        headers: { "Content-Type": "application/json" },
        "Access-Control-Allow-Credentials": true,
      })
      .then((data) => {
      
        setCoursesVdoList(data.data.data.lessons);
       
        setCompletedEpisode(data.data.data.lessonsCompleted)
   
        setExistingCourseID(data.data.data.courseID)       
      });
  };


useEffect(() => {
    courseVideo();
    const interval = setInterval(() => {
      setCount(!count)

    }, 300000)

  }, [count, completedEpisode]);

the count is used because I want to force rerender the component after 5 minutes.

CodePudding user response:

You can try using functional updater and clearing the timer

useEffect(() => {

    let ignore = false;

    // depends on courseID, username
    // need to include them in depedency
    courseVideo();

    const interval = setInterval(() => {
      if (ignore) {
        // skip setting state on unmounted component
        return;
      } 
    
      // use functional updater to remove dependency on count
      // as this will stop infinite render cycles
      setCount(c => !c)
    
      // without clearing this could trigger multiple times

    }, 300000)


   return () => {
       ignore = true;
       clearInterval(interval)
   }

  }, [completedEpisode]); //include courseID, username dependencies, they are used in courseVideo
   

You can read more about useEffect life cycle in the new beta docs

Hope it helps

CodePudding user response:

The courseVideo function is being called every time the component re-renders. It is being passed as a dependency to the useEffect hook. That why, it's multiples time.

You need to only call it when the component is initially rendered. You can clean up interval when the component unmounts.

useEffect(() => {
  courseVideo();
  const interval = setInterval(() => {
    setCount((prevCount) => !prevCount);
  }, 300000);

  return () => clearInterval(interval);
}, []);
  • Related