简体   繁体   中英

React useEffect hook doesn't clear interval

I'm trying to build a simple count down timer using react hooks to count down 3 seconds. But after 3 seconds UI stop rendering but in console.log I can still is prints out every second. Why is the second array parameter in useEffect doesn't prevent this from happening?

code sandbox

function CounterGame() {
  const [timeout, setTimeout] = React.useState(3);

  React.useEffect(() => {
    let id = window.setInterval(() => {
      if (timeout > 0) {
        setTimeout(x => x - 1 );
      }
      // this line keep executing even it timeout reach 0
      console.log("in setInterval", timeout);
    }, 1000)

    return () => {
      window.clearInterval(id);
    }
  }, [timeout])
  return (
    <div className="App">
      See instructions.
      <h1>{timeout} seconds</h1>
      {!timeout && <button>Click</button>}
    </div>
  );
}

const rootElement = document.getElementById("root");
ReactDOM.render(<CounterGame />, rootElement);

This may works for you:

clearIntervel when timeOut is zero by adding condition in useEffect

React.useEffect(() => {
      let id = window.setInterval(() => {
        if (timeout > 0) {
          setTimeout(x => x - 1 );
        }

    //clearIntervel here
        if(timeout == 0){
            window.clearInterval(id);
        }

        // this line keep executing even it timeout reach 0
        console.log("in setInterval", timeout);
      }, 1000)
  
      return () => {
        window.clearInterval(id);
      }
    }, [timeout])

According to theReact docs :

This is why React also cleans up effects from the previous render before running the effects next time.

Based on this, I believe that the cleanup function is not run until the next iteration of the useEffect . In your example, after timeout hits 0, the useEffect will run 1 more time, setting up a new interval, but because timeout is 0, it will not update the state, so the useEffect won't be called on the next render. That means the cleanup function never gets called for that last iteration.

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