setState 如何影响 setInterval?

How setState affects 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);
  };

Link沙盒

请解释一下,为什么它会那样工作,因为我认为 setInterval 中的回调引用了上面定义的时间,所以每次调用此回调时,它应该通过闭合爬升到定义时间的点,因此它应该获得新的价值。

time 是局部 const,您的间隔函数将关闭它。作为 const,它永远不会改变,因此您始终注销原始值。即使您使用 let,行为也是相同的,因为调用 setTime 确实 而不是 更改局部变量中的值。相反,它要求做出反应以重新渲染您的组件。在那个新的渲染上,一个新的局部变量将被创建为新的值,但是旧渲染中的代码(包括 setInterval 中的代码)仍然只有旧变量在其范围内并且无法访问新变量。

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

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

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

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

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

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