Home > Net >  Why does rerendering not effect counting with setTimeout?
Why does rerendering not effect counting with setTimeout?

Time:09-13

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.

  • Related