I need to have an infinite loop inside a useEffect for a continual process, however when the component gets unloaded the loop keeps going, I also have issues with the setTimeout cleanup and setTimeout violations in the console .. I have tried to use a cleanup function but to no avail?
function delay(time) {
return new Promise((resolve) => setTimeout(resolve, time));
}
useEffect(() => {
animate();
const animate = async (dates) => {
let i = 0;
await delay(5000);
while (true) {
console.log("setting");
await delay(1500);
if (i === dates.length - 1) {
i = 0;
} else {
i ;
}
}
};
}, []);
CodePudding user response:
The other answer's close, but if you want it to run continuously, what you need is setInterval()
(1). While also saving its ID to clear it on clean up.
useEffect(() => {
let interval;
animate();
const animate = (dates) => {
let i = 0;
interval = setInterval(() => {
console.log("setting");
if (i === dates.length - 1) {
i = 0;
} else {
i ;
}
}, 1500)
};
return () => clearInterval(interval)
}, []);
CodePudding user response:
You need to keep the timeout in memory and clear it in the cleanup function of the effect.
Here is a simplified example (also see jsfiddle):
function Animate() {
const [i, setI] = useState(1)
useEffect(() => {
const timeout = setTimeout(() => setI(v => v 1), 100)
return () => clearTimeout(timeout)
}, [i]) // Be sure to include `i` in dependency array
return <>{i}</>
}
As others suggested, using an interval instead of a timeout will work too. Maybe even better.