Reputation: 529
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
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
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