反应状态更新值显示在使用效果中,但内部函数仅显示旧值。
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 时不增加。
代码链接:https://codesandbox.io/s/bold-cdn-zzbs2?file=/src/App.js https://codesandbox.io/s/bold-cdn-zzbs2?file=/src/App.js
handleIncrease
仅在单击按钮时调用,并具有当前状态。单击处理程序中没有任何需要更新的内容。我认为您真正想要的是访问更新的counter
间隔回调中的状态,每秒“滴答”一次。或者更准确地说,响应isCounterContinue
状态切换 false 以在达到限制时停止间隔。
使用 ref 来保存对间隔计时器的引用,并使用它来设置/清除,而不是在外壳中陈旧的状态。
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>
</>
);
};
建议
除了添加到计数中的内容之外,增量/减量处理程序基本相同。使用柯里化函数通过关闭递增值来处理这两种情况。由于“停止”处理程序共享清除间隔的逻辑,因此请使用以下事实: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>
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)