javascript - setTimeout() 函数未检测到状态变化并继续执行递归函数
问题描述
useEffect(() => {
playLoop();
}, [state.playStatus]);
const playLoop = () => {
if (state.playStatus) {
setTimeout(() => {
console.log("Playing");
playLoop();
}, 2000);
} else {
console.log("Stopped");
return;
}
};
Output:
Stopped
// State Changed to true
Playing
Playing
Playing
Playing
// State Changed to false
Stopped
Playing // This is the problem, even the state is false this still goes on execute the Truthy stalemate
Playing
Playing
我正在研究 react-native,我希望在状态值变为 false 时停止递归。有没有其他方法可以实现这个代码我只想在状态值为真时重复执行一个函数。谢谢
解决方案
而不是一个playStatus
布尔值,我会保存间隔ID。这样,而不是设置playStatus
为false
,调用clearInterval
。同样,不要设置playStatus
为,而是true
调用setInterval
。
// Can't easily use useState here, because you want
// to be able to call clearInterval on the current interval's ID on unmount
// (and not on re-render) (interval ID can't be in an old state closure)
const intervalIdRef = useRef(-1);
const startLoop = () => {
// make sure this is not called while the prior interval is running
// or first call clearInterval(intervalIdRef.current)
intervalIdRef.current = setInterval(
() => { console.log('Playing'); },
2000
);
};
const stopLoop = () => {
clearInterval(intervalIdRef.current);
};
// When component unmounts, clean up the interval:
useEffect(() => stopLoop, []);
推荐阅读
- java - 使用对象属性作为函数参数
- javascript - JS中这个异步循环有更好的实现吗?
- python - 在折线图上添加垂直线扭曲比例
- c++ - 对类成员的未定义引用c ++
- sharepoint - 如何消除字符串;# 在三态工作流通知中添加到列表字段之前?
- swift - 使用 .transition 时图像未出现
- visual-studio-code - 我正在为自定义食物制作 Minecraft 数据包,但它不工作
- c# - 图像旋转保存位图
- flutter - 当 defaultPaneState 处于 CLOSED 状态时,窗格子上的按钮没有响应,直到热重新加载组件
- visual-studio - 无法启动 IIS Express Web 服务器 - 无法注册 URL - 当该文件已存在时无法创建该文件 | VS 社区 2017