Hello I would like to put setInterval in my React project to add 1 for each second but I got an error like in title of this post.
js:
const [activeTab, setActiveTab] = useState(0)
useEffect(() => {
setInterval(setActiveTab(prevTab => {
if (prevTab === 3) return 0
console.log('hi')
return prevTab += 1
}), 1000)
})
>Solution :
There are a few issues:
-
You’re not passing a function to
setInterval, you’re callingsetActiveTaband passing its return value intosetInterval. -
If you were passing in a function, you’d be adding a new repeated timer every time your componennt ran. See the documentation —
useEffect:By default, effects run after every completed render…
And
setInterval:The
setInterval()method… repeatedly calls a function or executes a code snippet, with a fixed time delay between each call.(my emphasis)
Starting a new repeating timer every time your component re-renders creates a lot of repeating timers.
-
Your component will leave the interval timer running if the component is unmounted. It should stop the interval timer.
To fix it, pass in a function, add a dependency array, and add a cleanup callback to stop the interval:
const [activeTab, setActiveTab] = useState(0);
useEffect(() => {
const handle = setInterval(() => { // *** A function
setActiveTab(prevTab => {
if (prevTab === 3) return 0;
console.log("?ghi");
return prevTab += 1;
});
}, 1000);
return () => { // *** Clear the interval on unmount
clearInterval(handle); // ***
}; // ***
}, []); // *** Empty dependency array = only run on mount
Side note: Assuming you don’t need the console.log, that state setter callback function can be simpler by using the remainder operator:
setActiveTab(prevTab => (prevTab + 1) % 3);