let updateTimer: number;
export function Timer() {
const [count, setCount] = React.useState<number>(0);
const [messages, setMessages] = React.useState<string[]>([]);
const start = () => {
updateTimer = setInterval(() => {
const m = [...messages];
m.push("called");
setMessages(m);
setCount(count + 1);
}, 1000);
};
const stop = () => {
clearInterval(updateTimer);
};
return (
<>
<div>{count}</div>
<button onClick={start}>Start</button>
<button onClick={stop}>Stop</button>
{messages.map((message, i) => (
<p key={i}>{message}</p>
))}
</>
);
}
Code Sample: https://codesandbox.io/s/romantic-wing-9yxw8?file=/src/App.tsx
The code has two buttons - Start and Stop.
Start calls a
setInterval
and saves interval id. Timer set to 1 second (1000 ms).Stop calls a
clearInterval
on the interval id.
The interval id is declared outside the component.
The interval callback function increments a counter and appends a called
message to the UI.
When I click on Start, I expect the counter to increment every second and a corresponding called
message appended underneath the buttons.
What actually happens is that on clicking Start, the counter is incremented just once, and so is the called
message.
If I click on Start again, the counter is incremented and subsequently reset back to its previous value.
If I keep clicking on Start, the counter keeps incrementing and resetting back to its previous value.
Can anyone explain this behavior?