setInterval updating state in React but not recognizing when time is 0
Asked Answered
A

1

4

I am practicing React useState hooks to make a quiz timer that resets every ten seconds. What I have now is updating the state each second, and the p tag renders accordingly. But when I console.log(seconds) it shows 10 every time, and so the condition (seconds === 0) is never met . In Chrome's React DevTools, the state is updating accordingly as well. What am I doing wrong here?

import React, {useState } from 'react';

function App() {

  const [seconds, setSeconds] = useState(10);

  const startTimer = () => {
    const interval = setInterval(() => {
      setSeconds(seconds => seconds - 1);

      // Logs 10 every time
      console.log(seconds)

      // Never meets this condition
      if (seconds === 0) {
            clearInterval(interval)
      }
    }, 1000);
  }

  return (
    <div>
      <button onClick={() => startTimer()}></button>
      // updates with current seconds
      <p>{seconds}</p>
    </div>
  )
}

export default App;
Anglicism answered 26/8, 2020 at 19:6 Comment(0)
R
3

That is because the setSeconds updates the state with a new variable on every tick but the initial reference (seconds === 10) still points to the initial set variable. That is why it stays at 10 => The initial reference. To get the current value, you have to check it in the setSeconds variable (passed as seconds) like this:

const startTimer = () => {
    const interval = setInterval(() => {
      setSeconds(seconds => {
        if(seconds < 1) {
          clearInterval(interval);
          return 10;
        }
        return seconds - 1;
      });
    }, 1000);
  }

Here is a working sandbox

You should also rename the variable to not have the same name (seconds) twice in a single funtion.

Repugnant answered 26/8, 2020 at 19:28 Comment(2)
Thank you! Makes sense. So in the setSeconds part, I can use any name in place of “seconds”, correct?Anglicism
Yes, any name is fine. You can also use the seconds but is dis-encouraged to avoid confusion.Repugnant

© 2022 - 2024 — McMap. All rights reserved.