I have a component with controlled inputs. This component is also a parent for a Timer component. The Timer component counts down from 20 to 0 using setTimeout. Right now the child component rerenders on every key stroke (and therefore the state change) in a parent component.
const Timer = () => {
const [secondsLeft, setSecondsLeft] = useState(20);
if (secondsLeft) {
setTimeout(() => setSecondsLeft(secondsLeft - 1), 1000);
}
const displayTime = '00:' String(secondsLeft).padStart(2, '0');
if (secondsLeft > 0) {
return <span>Time left {displayTime}</span>;
}
return <span>You're out of time!</span>;
};
My question is why the countdown timer works properly and it's interval is always exacly 1 second no matter how fast I type in a parent input element. Why rerendering does not affect the setTimeout?
CodePudding user response:
If you update 5 times in a second, you now have 5 timers that will call setSecondsLeft(secondsLeft - 1)
for that second. Luckily only the first one triggers a rerender because the subsequent calls don't change the value.
Try using:
setSecondsLeft(secondsLeft => secondsLeft - 1)
Note: answer provided by Thomas on comment section.