There are a few issues:
You're not passing a function to setInterval, you're calling setActiveTab and passing its return value into setInterval.
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);