Bassel Turky
Bassel Turky

Reputation: 529

React setInterval function keeps running in the background after rerender

I am using setInterval inside useEffect with an empty dependency array inside one of my react components. There is true/false useState which controls the display of that component. When the state is false, the component is hidden and when it's true the component is shown.

Something like this:

const [state, setState] = useState(false)

// in jsx render section

return (
   <div>
      {state? <component/> : '' }
   </div>
)

When the component loads for the first time the setInterval runs only one time which is what it supposes to do.

If the state goes to false then back to true, the component is removed from the UI and is then displayed back again. However, what happens here is now I have two setInterval functions running in the background, and the first one doesn't shutdown.

The number of the setInterval functions keeps increasing with each time that component re-render.

I don't understand how React works in this situation.

I need to know how it works (i.e. why won't the function shutdown, why are the number of functions increasing) and how to fix it.

Upvotes: 1

Views: 4326

Answers (2)

Muhammad Raqib
Muhammad Raqib

Reputation: 344

I have used answer number one of Sidharth, but it did not work always, this is actually an issue in React Native and react native has already added another hook to deal with this.

If you are here from react native then you can remove the screen from the navigation stack which is not an optimal answer but will do the job for now.

you can do something like this

navigation.replace("NextScreen)

this will remove the current screen completely from the stack and obviously, if the screen is removed everything in the screen will get removed hence the setInterval as well.

Upvotes: 0

Siddharth Varangaonkar
Siddharth Varangaonkar

Reputation: 451

This is the structure of React useEffect.React performs the cleanup when the component unmounts.

useEffect(() => {
    //effect
    return () => {
        //cleanup runs on unmount
    }
}, [])

The cleanup function should have clearInterval() which will basically removes setInterval or stops it when component unmounts. See the practical code below:

let intervalid;
useEffect(
    () => {
     intervalid = setInterval(() => {console.log("Iterate");}, 1000));

      return function cleanup() {
        console.log("cleaning up");
        clearInterval(intervalid);
      };
    },
    []
  );

This above code is just for understanding approach. Every effect may return a function that cleans up after it. This lets us keep the logic for adding and removing subscriptions close to each other. # FROM REACT DOCS Reference

Upvotes: 5

Related Questions