更新的状态值不会在反应中的函数内部更新

updated state value are not updated inside function in react

反应状态更新值显示在使用效果中,但内部函数只显示旧值。

const [counter, setCounter] = useState(0);

我正在尝试更新设置间隔函数内的计数器值

 const handleIncrease = () => {
clearInterval(intervalval);
if (counter < 10) {
  let increment = setInterval(() => {
    console.log("isCounterContinue@handleIncrease", counter);
    setCounter((prev) => prev + 1);
  }, 1000);
  setIntervalval(increment);
}

}; 显示内部 useEffect 更新值。但在函数 handleIncrease 内部只显示旧值 基本上,我试图做的是计数器值在超过 30 时不增加。

代码 Link : https://codesandbox.io/s/bold-cdn-zzbs2?file=/src/App.js

handleIncrease 仅在单击按钮时以当前状态调用。单击处理程序中没有要更新的内容。我认为你真正想要的是访问间隔回调中更新的 counter 状态,它每秒“滴答”一次。或者更准确地说,响应 isCounterContinue 状态切换 false 以在达到限制时停止间隔。

使用 ref 来保存对间隔计时器的引用,并且 set/clear 使用它而不是在外壳中变得陈旧的状态。

const Timer = () => {
  const [counter, setCounter] = useState(0);
  const intervalRef = useRef();

  useEffect(() => {
    console.log({ counter });
    if (counter >= 5) {
      clearInterval(intervalRef.current);
    }
  }, [counter]);

  const handleIncrease = () => {
    clearInterval(intervalRef.current);
    intervalRef.current = setInterval(() => {
      setCounter((prev) => prev + 1);
    }, 1000);
  };

  const handleDecrease = () => {
    clearInterval(intervalRef.current);
    intervalRef.current = setInterval(() => {
      setCounter((prev) => prev - 1);
    }, 1000);
  };

  const handleStop = () => {
    clearInterval(intervalRef.current);
  };

  return (
    <>
      <div>{counter}</div>
      <div>
        <button onClick={handleDecrease}>Decrease</button>
        <button onClick={handleStop}>Stop</button>
        <button onClick={handleIncrease}>Increase</button>
      </div>
    </>
  );
};

建议

increment/decrement 处理程序除了添加到计数中的内容外基本相同。使用柯里化函数通过关闭增量值来处理这两种情况。由于“停止”处理程序共享清除间隔的逻辑,因此使用 0 是一个错误值这一事实,并且只为真值(即非零)数值重新启动间隔计时器,并对所有三个值使用一个处理程序按钮。

const handleIncrease = (val) => () => {
  clearInterval(intervalRef.current);
  if (val) {
    intervalRef.current = setInterval(() => {
      setCounter((prev) => prev + val);
    }, 1000);
  }
};

...

<button onClick={handleIncrease(-1)}>Decrease</button>
<button onClick={handleIncrease(0)}>Stop</button>
<button onClick={handleIncrease(1)}>Increase</button>