简体   繁体   中英

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

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;

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.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM