使用 setInterval 更改 useState 的值

change the value of useState with setInterval

我有一个带有 useState 的简单组件,每次点击都会增加一个计数器 -

function Counter() {
  let [counter, setCounter] = useState(0);

  const incCounter = () => {
    setCounter(counter + 1);
  };

  return (
    <div className="App">
      <h1>{counter}</h1>

      <button onClick={incCounter}>Inc</button>
    </div>
  );
}

Here is its demo

现在我想每1秒调用一次increase函数,所以我将这段代码添加到组件函数中-

useEffect(() => {
    setInterval(() => {
      incCounter();
    }, 1000);
  }, []); 

Here is its demo

但我没有看到组件中的计数器增加。

我应该如何正确编写它并看到计数器按预期每 1 秒增加一次?

问题

您有一个来自设置定时器回调的渲染周期的状态值的陈旧外壳。

解决方案

使用功能状态更新,以便状态从先前的状态更新,而不是更新排队的渲染周期的状态。这允许间隔回调 单击处理程序以无缝更新状态,彼此独立。

setCounter(counter => counter + 1);

事实上,您应该随时使用功能状态更新,下一个状态值取决于任何先前的状态值。增加计数器是使用功能更新的经典示例。

不要忘记return一个清除函数来清除组件卸载时的间隔。

完整代码

function Counter() {
  let [counter, setCounter] = useState(0);

  const incCounter = () => {
    setCounter((counter) => counter + 1);
  };

  useEffect(() => {
    const timerId = setInterval(() => {
      incCounter();
    }, 1000);

    return () => clearInterval(timerId);
  }, []);

  return (
    <div className="App">
      <h1>{counter}</h1>

      <button onClick={incCounter}>Inc</button>
    </div>
  );
}

演示