I just started learning react and I have about a performance question. I want to increment a counter using the setInterval function and then reset it when the length of the array is reached. The problem is I need to add an active
variable for the useEffect dependency, which removes the interval and then creates it again.
useEffect(() => {
const timer = setInterval(() => {
active == arr.length - 1 ? setActive(0) : setActive((active) => active + 1)
}, 3000)
return () => clearInterval(timer)
}, [active])
So, I wrote code like this, which looks crazy, but does the same job without removing the interval, and gets the actual version of the active
variable from the callback.
useEffect(() => {
const timer = setInterval(() => {
setActive((active) => (active === arr.length - 1 ? active == 0 : active + 1))
}, 3000)
return () => clearInterval(timer)
}, [])
The question is how best to write and not do unnecessary work in the component
I would probably split all this logic out into a couple effects.
One to manage incrementing active
on the interval and clearing the interval when the component unmounts.
useEffect(() => {
const timer = setInterval(() => {
setActive(active => active + 1);
}, 3000);
return () => clearInterval(timer);
}, []);
A second to reset the state on the condition.
useEffect(() => {
if (active === arr.length - 1) {
setActive(0);
}
}, [active, arr]);
I would also caution you to protect against the edge case where active
is updated to 0 and the arr
array is an array of length 1 as this will trigger render looping.