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);
}, []);