gpt4 book ai didi

javascript - 将 useState 与 setInterval 内的 if 条件一起使用不起作用

转载 作者:行者123 更新时间:2023-12-04 07:13:23 24 4
gpt4 key购买 nike

import { useState, useEffect } from "react";
import "./styles.css";

export default function App() {
const [progress, setProgress] = useState(0);

let progressTimer;

function handleTime() {
if (progress <= 100) {
console.log("Progress: " + progress);
setProgress((prevState) => (prevState += 10));
} else {
console.log("greater");
clearInterval(progressTimer);
}
}

function handlePlay() {
console.log("Timer start");
progressTimer = setInterval(handleTime, 1000);
}

useEffect(() => {
handlePlay();
});

return (
<div className="App">
<h1>Hello CodeSandbox</h1>
{progress}
<h2>Start editing to see some magic happen!</h2>
</div>
);
}

Codesandbox Link

期望的结果:转到 100,每 1 秒数 10。达到 100 多个后,关闭计时器。

实际结果:它一直在上升,每 1 秒超过 10。

最佳答案

问题

  1. 启动间隔的 useEffect 没有依赖数组,因此每次呈现组件时都会启动一个新的间隔。这就是导致跳跃越来越大的原因。
  2. progressTimer 会在每个渲染周期重新声明,因此无法清除它。
  3. 当传递给 setInterval 回调时,progress 状态的检查在回调范围内关闭。您只会查看初始状态值。换句话说,这是一个陈旧的围栏。
  4. 在功能状态更新中使用 prevState => (prevState += 10) 实际上会改变先前的状态。应避免所有状态突变。

解决方案

  1. 将依赖项数组添加到 useEffect 以便它在组件安装时运行一次。将 handlePlay 逻辑移动到效果回调中,以便在安装时没有外部依赖性。不要忘记返回清理函数以清除组件卸载时的任何运行间隔。
  2. progressTimer 存储为 React 引用,使其成为稳定的引用。
  3. 解除状态更新与清除计时器副作用的混合。使用第二个 useEffect Hook 来检查当前 progress 值何时达到 100。
  4. 在状态更新器中只返回前一个状态加 10,prevState => prevState + 10 作为下一个状态值。

代码

function App() {
const [progress, setProgress] = useState(0);

const progressTimer = useRef();

function handleTime() {
setProgress((prevState) => prevState + 10);
}

useEffect(() => {
console.log("Progress: " + progress);
if (progress >= 100) clearInterval(progressTimer.current);
}, [progress]);

useEffect(() => {
console.log("Timer start");
progressTimer.current = setInterval(handleTime, 1000);

return () => clearInterval(progressTimer.current);
}, []);

return (
<div className="App">
<h1>Hello CodeSandbox</h1>
{progress}
<h2>Start editing to see some magic happen!</h2>
</div>
);
}

Edit using-usestate-with-an-if-conditional-inside-of-setinterval-isnt-working (forked)

关于javascript - 将 useState 与 setInterval 内的 if 条件一起使用不起作用,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/68932007/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com