It’s passing everything but 12 and 13. It counts down from 5 to 2 and then jumps to the expiration message, skipping 1 and 0, the first time I run it. And then in subsequent runs, it starts at 0, then goes to 5 and counts down to 2 again. I can’t figure out what I’m doing wrong.
It’s not guaranteed that after new timerCount is set, the next line will already have updated value (it’s almost guaranteed to be the opposite).
What might be even more surprising, when calling setTimerCount(timerCount - 1), it’s not guaranteed, the timerCount will be the latest value. See useState – React
Reading further down, into the troubleshooting section, I read:
"This is because states behaves like a snapshot. Updating state requests another render with the new state value, but does not affect the count JavaScript variable in your already-running event handler.
If you need to use the next state, you can save it in a variable before passing it to the set function"
So I tried doing it by setting a new variable to timerCount +1 and then setting timerCount to the new variable, and that also had no effect.
I feel like I’ve totally missed the point of whatever it is you’re trying to tell me.
I didn’t look at it over the weekend (I mostly do these courses in my downtime at my job, and I was off) so I don’t super remember where I was at. I think I just changed everything to use the “prev => newvalue” format, and it didn’t make a difference. Current code, as I left it on Friday:
That’s what it’s supposed to be, yes. I’m trying to first update the value of timerCount and then update the message displayed by timerBox to reflect that. But it’s not behaving that way. It’s updating the displayed message immediately but not updating the value of timerCount immediately. I think.
I don’t know. useEffect is set to refresh whenever timerCount or isDisabled are changed, and setInterval is set to subtract 1 from timerCount every 1000 ms, per my understanding of my code, so I clearly don’t understand what my code is doing. When I log timerCount to console, I can see that it is being properly modified every second, but it is not being reflected in the message countdown.
I moved the setTimerBox command to outside of the setInterval block, and that fixed the countdown not going to 0, and starting lagged, but it broke setting the expiry message. So I put the setTimerBox in an if-block so that it wouldn’t update it if it were not above 0, and that made the whole thing work, as below:
useEffect(() => {
if (!isDisabled) {
setTimerCount(5);
return;
}
if (timerCount == 0) {
setTimerBox("OTP expired. Click the button to generate a new OTP.");
setIsDisabled(prev => false);
}
if (timerCount > 0) {
setTimerBox(prev => `Expires in: ${timerCount} seconds`);
}
const counter = setInterval(() => {
const newCount = timerCount - 1
setTimerCount(prev => newCount);
}, 1000)
return () => clearInterval(counter);
}, [timerCount, isDisabled])
I don’t think I really understand why, tho. Thank you for your time and patience!