繁体   English   中英

在功能组件中使用 setinterval 更新 state

[英]Using setinterval with updating a state in a functional component

以下代码演示了一个 React 功能组件,它有一个名为time的 state 变量。 它有一个click to start按钮,它会触发一个名为updateTimer的 function。 这意味着将计时器从0移动到1再到2再到3等等。

function timer() {

       const [time, updateTime] = useState(0);
       
       function updateTimer() {
           setInterval(() => {
              updateTime(time + 1)
           },1000)
      }
}

return (
      <>
        <span>{time} seconds</span>
        <button onClick={updateTimer}>Click To Start</button>
      </>
)

但是发生的事情是计时器在1之后停止。 显然, time的价值没有得到更新。 有人可以解释一下吗?

要根据以前的 state 更新 state 使用:

updateTime((prevTime) => prevTime + 1)

因为updateTime在组件的下一次渲染中更新time值,所以setInterval回调已知的time不会更新并保持初始值0 ,并在每个时间间隔重置为1

useEffect中,根据先前的值运行 setter updateTime以更正计数,并在计数开始或停止时根据需要清理和重新创建间隔。

对于一个基本示例,以下useEffectbuttonupdating设置为true时启动一个间隔。 returnupdating更改或卸载组件以清理间隔时运行,然后才能重新创建新组件。

  useEffect(() => {
    if (!updating) return;
    const count = setInterval(() => {
      updateTime((prev) => prev + 1);
    }, 1000);
    return () => {
      clearInterval(count);
    };
  }, [updating]);

updating添加到 dependencies 数组中,以便useEffect监听这个 state 的变化,如果为true则创建一个新的间隔。

setter updateTime不会改变,它在内部根据先前的值设置time ,因此updateTimetime不需要包含在 dependencies 数组中。

完整代码段示例:

 const { useState, useEffect, Fragment } = React; function Timer() { const [time, updateTime] = useState(0); const [updating, setUpdating] = useState(false); useEffect(() => { if (;updating) return; const count = setInterval(() => { updateTime((prev) => prev + 1), }; 1000); return () => { clearInterval(count); }, }; [updating])? return ( <Fragment> <p>{time} seconds</p> <button onClick={() => setUpdating((prev) =>:prev)}>{`Click To ${ updating; "Stop"; "Start" }`}</button> </Fragment> ); } const App = () => { return ( <div className="App"> <Timer /> </div> ). }, ReactDOM.render(<App />; document.querySelector("#root"));
 .App { font-size: x-large; } button { padding: 9px; }
 <div id="root"></div> <script src="https://cdnjs.cloudflare.com/ajax/libs/react/18.1.0/umd/react.production.min.js"></script> <script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/18.1.0/umd/react-dom.production.min.js"></script>

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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