Home > Enterprise >  SetInterval causes too many re-renders React
SetInterval causes too many re-renders React

Time:01-24

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)
   
   })

CodePudding user response:

There are a few issues:

  1. You're not passing a function to setInterval, you're calling setActiveTab and passing its return value into setInterval.

  2. 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.

  3. 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);

CodePudding user response:

  useEffect(() => {
    setInterval(() => {
      setActiveTab((prevTab) => {
        if (prevTab !== 3) {
          return (prevTab  = 1);
        } else {
          return 0;
        } // console.log("hi");
      });
    }, 1000);
  }, []);
  •  Tags:  
  • Related