reactjs - setState 如何影响 setInterval?

我编写了简单的计时器,但是当我尝试 console.log(time)(它在 handleStart 中)时,我得到相同的输出 0,即使调用了 setTime()

这是代码的一部分,我 console.log(time) (它在 handleStart 中,您应该单击“开始”按钮才能看到 console.log):

const handleStart = () => {
    setIsCounting(true);
    timerIntervalRef.current = setInterval(() => {
      console.log(time);
      setTime((prevState) => {
        localStorage.setItem("time", `${prevState + 1}`);
        return prevState + 1;
      });
    }, 1000);
  };

https://codesandbox.io/s/inspiring-wozniak-6yuhju?file=/src/App.js到沙盒

请解释一下,为什么它会这样工作,因为我认为,setInterval 中的回调引用了上面定义的时间,所以每次调用这个回调时,它都应该通过闭包爬到定义时间的点,所以它应该被更新value。

回答1

time 是一个本地 const,您的区间函数会关闭它。作为一个const,它永远不会改变,所以你总是退出原来的value。即使您使用了 let,行为也会相同,因为调用 setTime 不会更改局部变量中的 value。相反,它要求 react 重新渲染您的组件。在该新渲染中,将使用新的 value 创建一个新的局部变量,但旧渲染中的代码(包括 setInterval 中的代码)仍然只有旧变量在其范围内,无法访问新变量.

如果您想验证组件是否正在重新呈现,您可以将日志语句移动到组件的主体中。

console.log('rendering with', time); // moved outside of handle start

const handleStart = () => {
  // ... normal handleStart function, minus the console.log
}

或者,如果您在设置状态时想要一条日志语句,则可以将其移动到 set state 函数中,因为它会传递状态的最新 value 并且不依赖于闭包变量:

setTime((prevState) => {
   console.log(prevState);
   localStorage.setItem("time", `${prevState + 1}`);
   return prevState + 1;
});

回答2

在 settime 内你得到更新的 value (prevState),“时间”是指初始时间,consoling 显然是指初始 value,我认为你应该 console.log(prevState)

相似文章

最新文章