javascript - 反应状态没有正确更新
问题描述
我正在研究番茄钟,在休息后切换回番茄钟时遇到问题。
const start = () => {
//this stop function clears the pre-existing timer if there is any.
stop();
setTimerOn(true);
let interval = setInterval(() => {
setDisplayTime((prev) => {
//onBreak is false by default
if (prev <= 0 && !onBreak) {
setOnBreak(true);
return breakDuration;
}
// this if statement is not being executed
if (prev <= 0 && onBreak) {
setOnBreak(false);
return sessionDuration;
}
return prev - 1;
});
}, 1000);
//save the timer insatance in react state
setTimer(interval);
};
每当计时器变为 0 时,我都会更新 onBreak 的状态。但是当我在反应开发工具中检查 onBreak 的状态时,只有首先执行块,然后状态永远不会改变。执行第一个 if 语句后,代码进入无限循环,只有 breakSession 被一遍又一遍地执行。
解决方案
您的代码的问题是您传递给的函数setInterval
保存了onBreak
它创建时的值;它无法获取当前状态onBreak
。(我假设[onBreak, setOnBreak] = useState()
。)
传递可变状态的一种方法是useRef
. 像这样的东西:
const [onBreak, setOnBreak] = useState();
// Create a ref whose value is set automatically to onBreak
const onBreakRef = useRef();
useLayoutEffect(() => {
onBreakRef.current = onBreak;
}, [onBreak]);
const start = () => {
//this stop function clears the pre-existing timer if there is any.
stop();
setTimerOn(true);
let interval = setInterval(() => {
setDisplayTime((prev) => {
if (prev <= 0 && !onBreakRef.current) {
setOnBreak(true);
return breakDuration;
}
if (prev <= 0 && onBreakRef.current) {
setOnBreak(false);
return sessionDuration;
}
return prev - 1;
});
}, 1000);
//save the timer insatance in react state
setTimer(interval);
};
这段代码虽然感觉很乱。您能否改为在对 when issetOnBreak(false)
做出反应的其他代码中执行?然后代码可以无条件地当.onBreak
true
setInterval
setOnBreak(true)
prev <= 0
推荐阅读
- ios - 如何启动特定的 iOS 模拟器?
- heremaps-android-sdk - 有没有办法修改 NavigationManager.RoadView 缩放行为?
- c# - 是否有使用 HostBuilder 访问命令行参数的类型安全方法?
- python - Python 运行时类型检查传递给装饰器的函数是否具有正确的签名
- python-3.x - 如何通过使用python添加特殊字符来替换句子(如果它已经存在,请避免)
- c++ - 了解 sem_open()
- python - KeyError: 'date' while set date column as a index with pandas
- c++ - 数组和 std::vector 的谷歌基准性能显示数组的 cpu 时间 = 0ns?为什么
- python - 如何为两个窗口放置标识?
- python - 创建具有相同键的字典列表