I would like to stop setInterval
using clearInterval()
. But intervalId
is undefined
. I don’t know why.
import { useState } from 'react';
function Component() {
const [counter, setCounter] = useState(0);
function addToCounter() {
setCounter((c) => c + 1);
}
let intervalId;
function runInterval() {
intervalId = setInterval(addToCounter, 1000);
console.log(intervalId);
}
function stopInterval() {
clearInterval(intervalId);
console.log(intervalId);
}
return (
<>
<p>Value :{counter}</p>
<button onClick={runInterval}>start interval</button>
<button onClick={stopInterval}>stop interval</button>
</>
);
}
export default Component;
It works when line
intervalId = setInterval(addToCounter, 1000);
is replaced by
intervalId = setInterval(()=>console.log(intervalId), 1000);
2
Answers
addToCounter
updates state, which re-renders the component, which declares a newintervalId
so the one for your interval has been lost.There are various ways to approach the overall goal, including the use of
useEffect
. For the least amount of changes to the current code, simply storing the interval identifier in state should at least persist it across renders. For example:The answer is in how React works. In first case you pass function addToCounter to the interval. Function addToCounter have setCounter which is setter from useState hook. When there is a setting of a new state, React rerenders the component. On every rerender intervalId have undefined value at the beginning. For that it do not stops the interval, because the id is lost.
In the second case () => console.log() do not trigger rerender, the id is kept in intervalId and it works.