Reputation: 1319
I'm wondering what is the correct way and best practice to clear timeouts/intervals when using React hooks. For example I have the following code:
import React, { useState, useEffect, useRef } from 'react';
const Test = () => {
const id = useRef(null)
const [count, setCount] = useState(5)
const [timesClicked, setTimesClicked] = useState(0)
if (!count) {
clearInterval(id.current)
}
useEffect(() => {
id.current = setInterval(() => {
setCount(count => count -1)
}, 1000)
return () => {
clearInterval(id.current)
}
}, [])
const onClick = () => setTimesClicked(timesClicked => timesClicked + 1)
return (
<div>countdown: {count >= 0 ? count : 0}
<hr />
Clicked so far: {timesClicked}
{count >= 0 && <button onClick={onClick}>Click</button>}
</div>
)
}
When count
equals 0 the interval is cleared in the body of the Test
function. In most of the examples I've seen on the Internet interval is cleared inside useEffect
, is this mandatory?
Upvotes: 4
Views: 1316
Reputation: 665
You must be sure to clear all intervals before your component gets unmounted.
Intervals never disappear automatically when components get unmounted and to clear them, clearInterval
is often called inside useEffect(() => {}, []).
The function retured in useEffect(() => {}, []) gets called when the compoment is unmounted.
return () => {
clearInterval(id.current)
}
You can see that intervals set inside a component never disappears automatically by checking this sandbox link. https://codesandbox.io/s/cool-water-oij8s
Intervals remain forever unless clearInterval
is called.
Upvotes: 5
Reputation: 76905
setInterval
is a function
which is executed repeatedly and it returns an id
of the interval. When you call clearInterval
with this id, you stop that function
from repeating. It's not mandatory to do it inside a certain function
, you need to clear it when you no longer want that function
to be called subsequently. You can call it in the function
you return as a result of useEffect
, if that's what you need.
Upvotes: 1