javascript - 为什么在 clearTimeout 之后 SetTimeout 代码仍然执行
问题描述
我的反应组件中有以下代码:
//some code
var timeout = null; //global variable
//some more code
useEffect(() => {
if(...some condition) {
console.log('test1');
timeout = setTimeout(() => {
console.log('test2');
}, 15 * 1000);
} else {
console.log('test3');
clearTimeout(timeout);
}
}, [some other condition]);
我在控制台中得到的输出:
test1
test3
test2 //after 15 seconds
因此,如果在此期间未清除超时,我正在尝试启动将记录“test2”的超时。正如我们所见,记录了“test3”,这意味着超时已被清除,但 15 秒后仍然记录了“test2”。这里有什么问题?
解决方案
您需要ref
像这样保存超时,每次组件重新呈现时都会有一个新的超时实例,这就是为什么当clearTimeout
它不起作用时,因为它清除了错误的计时器:
const timeout = useRef(null); //global variable
const [test, setTest] = useState(true);
//some more code
setTimeout(() => {
console.log("setting");
setTest(false);
}, 2000);
useEffect(() => {
if (test) {
console.log("test1");
timeout.current = setTimeout(() => {
console.log("test2");
}, 5 * 1000);
} else {
console.log("test3");
clearTimeout(timeout.current);
}
return () => clearTimeout(timeout.current) // clearing on unmount
}, [test]);
上面的代码输出如下:
test1
setting
test3
setting
你可以在这里试试:https ://codesandbox.io/s/boring-waterfall-6f6iv?file=/src/App.js
推荐阅读
- django - 如何在 django 查询中使用列表
- c++ - 模板库中的名称查找:我们为什么要添加这个->
- java - Android gradle:从外部依赖项中排除文件
- cross-browser - 我的应用程序不能在 IE 浏览器上运行,我有 abp-zero-template 6.5.0 和 angular vesrion 7.1.0
- scala - Scala scala.xml.XML.load(is: InputStream) 正在关闭 ZipInputStream
- git - git lfs 不是命令 Mac OS
- python - Python 自动打开应用程序
- elasticsearch - 配置elasticsearch集群时出错
- opencv - 如何在openCV中找到霍夫线之间的距离?
- excel - Excel中奇怪的排序逻辑:引用其他单元格值的单元格