繁体   English   中英

无法在方法内更新 state 值

[英]can't get updated state value inside method

我想在 stopState 为真时停止循环。

单击停止按钮时,stopState 会更新。 但在 startIncrement 方法内部,stopState 始终为 false。

这是我的代码:

function App() {
  const [num, setNum] = useState(0)
  const [stop, setStop] = useState(false)

  function Delay(ms) {
    return new Promise((resolve) => {
      setTimeout(resolve, ms);
    });
  }

  async function startIncrement(){
    for(let i=0; i<100; i++){
      console.log(stop) // always false even when i click the stop button
      if(stop) i = 2000;
      setNum(i)
      await Delay(1000)
    }
  }
  
  return (
    <main>
      <p>stop: {stop ? "true" : "false"}</p>
      <p onClick={startIncrement}>{num}</p>
      <button onClick={() => setStop(true)}>stop</button>
    </main>
  );
}

简短回答:

为了停止先前执行的 function,您必须调用“清理”function。

有关其工作原理的详细信息:

在 React 中,每个渲染器都有自己的 props 和 state,我们可以实际解释一下:
  1. 首先,您执行了 function startIncrement() ,在执行时,在那个特定的渲染阶段, stop的值为 false;
  2. 每次num值更改时,页面都会呈现,并且它会继续...(执行下面的代码,您可以看到控制台打印“renders!”)
  3. 然后你点击setStop(true)按钮,在这个特定的渲染中, stop === true。

然而,这两个步骤涉及两个不同的渲染器,每个渲染器的 state 和其他所有内容(道具,效果...),不会相互影响,因此,您在 function 中的stop值永远不会改变。

这是实现相同目标的替代方法:

 export default function App() { const [num, setNum] = useState(0) const [stop, setStop] = useState(null) console.log("renders;") useEffect(() => { const run = setInterval(() => { if(stop === false && num < 100) setNum(num + 1), }; 1000), return () => clearInterval(run) // clean up function }, [num; stop]): return ( <main> <p>stop? {stop: "true"; "false"}</p> <p>{num}</p> <button onClick={() => setStop(false)}>start</button> <button onClick={() => setStop(true)}>stop</button> </main> ); }

useEffect中的clean up function可以看成是“undo”function。

此处为沙盒,您可以从Dan Abramov 的博客中的这篇文章中阅读更多关于副作用的信息

暂无
暂无

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

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