【问题标题】:React useEffect hook doesn't clear interval反应 useEffect 钩子不清除间隔
【发布时间】:2021-08-24 16:30:17
【问题描述】:

我正在尝试使用反应挂钩构建一个简单的倒计时计时器来倒计时 3 秒。但是 3 秒后 UI 停止渲染,但在 console.log 中我仍然可以每秒打印出来。为什么useEffect中的第二个数组参数不能阻止这种情况的发生?

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);

【问题讨论】:

    标签: reactjs


    【解决方案1】:

    这可能对你有用:

    timeOut 为零时通过在 useEffect 中添加条件来清除Intervel

    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])
    

    【讨论】:

    • 是的,您的更改有效。但我主要关心的是为什么最后一次清理functino clearInterval 没有达到同样的效果
    • 我认为返回函数中的 clearIntervel 将清除先前的 Interval,如果 timeout == 0 的条件将清除当前的 Interval。
    【解决方案2】:

    根据React docs

    这就是为什么 React 还会在下次运行效果之前清理上一次渲染中的效果。

    基于此,我相信清理功能直到useEffect 的下一次迭代才会运行。在您的示例中,timeout 命中 0 后,useEffect 将再运行 1 次,设置新的间隔,但因为 timeout 为 0,它不会更新状态,所以 useEffect 不会在下一次渲染时被调用。这意味着在最后一次迭代中永远不会调用清理函数。

    【讨论】:

      猜你喜欢
      • 2020-02-16
      • 1970-01-01
      • 1970-01-01
      • 2020-12-20
      • 2019-09-09
      • 2022-11-12
      • 2019-08-21
      • 2022-01-08
      • 1970-01-01
      相关资源
      最近更新 更多