为何满足if条件时setTimeout仍会触发?
问题根源与解决方案
问题出在哪?
你代码里的timer是then回调内部的局部变量,每次useEffect触发时都会生成新的timer实例——这意味着你在if分支里调用clearTimeout(timer)时,清的是一个未赋值的空变量,根本碰不到之前创建的定时器。再加上useEffect依赖loginTriggers和goodByeLoading,只要这些值变了,effect就会重新执行,之前没清的定时器到点照样触发,哪怕这次满足token存在的条件。
怎么改?
用useRef存储定时器引用,它能在组件整个生命周期里保持同一个引用,不会随渲染重置。这样不管effect跑多少次,都能拿到之前的定时器并清除:
import { useEffect, useRef } from 'react'; // ... useEffect(() => { const timerRef = useRef(null); AsyncStorage.getItem('token') .then(token => { console.log('AsyncStorage (token): ', token); console.log('Is token not null? ', token !== null); // 先清掉之前可能残留的定时器 if (timerRef.current) { clearTimeout(timerRef.current); timerRef.current = null; } if (token) { dispatch(getUserInfoByToken(token)); } else { dispatch(data_not_initialized()); timerRef.current = setTimeout(() => { dispatch(tokenIsNull()); }, 3000); } }) .catch(error => { console.log(error); }); // 组件卸载或effect重新执行时,清掉定时器避免泄漏 return () => { if (timerRef.current) clearTimeout(timerRef.current); }; }, [loginTriggers, goodByeLoading]);
关键细节
- 每次处理
token前先清除旧定时器,确保分支逻辑不会被残留定时器干扰。 - 加上
useEffect的清理函数,组件卸载或依赖变化时自动清定时器,防止内存泄漏和报错。
补充说明:已移除之前尝试添加的clearTimeout,目前问题已解决,感谢大家。
内容的提问来源于stack exchange,提问作者Almighty Dee
相关产品推荐
相关产品推荐

