useEffect内清理onAuthStateChanged报错,unsubscribe调用未生效是什么原因
问题原因分析
你已经正确取消了onAuthStateChanged的auth状态监听订阅,本质上「订阅未取消」是假象,问题出在监听回调内部的逻辑没有配套清理:
- 你只清理了auth状态监听的订阅,但是回调中创建的
setInterval定时器没有被清理。就算监听被取消,已经提交到事件循环的定时器回调依然会在1500ms后触发执行,看起来就像是订阅没有成功取消。 - 如果auth状态多次切换,每次监听触发都会生成新的
setInterval实例,没有清理的话会堆积大量未执行的定时器,就算取消了监听,这些定时器的回调依然会依次执行,放大异常表现。 - 额外的逻辑问题:你的业务场景只需要单次延迟执行跳转、状态更新,用
setInterval会导致回调重复触发,本身就不符合需求。
修复方案
同时清理定时器和auth订阅即可解决问题,修复后的代码如下:
useEffect(() => { let timerId = null; const unsubscribe = onAuthStateChanged(auth, (user) => { // 每次状态变化先清理之前的定时器,避免堆积 if (timerId) clearTimeout(timerId); if(user){ // 替换为单次执行的setTimeout符合业务需求 timerId = setTimeout(()=>{ setUser(user) history.push('/home') }, 1500) } else { timerId = setTimeout(()=>{ history.push('/login') }, 1500) } }) // 清理逻辑:先清未执行的定时器,再取消auth订阅 return ()=> { if (timerId) clearTimeout(timerId); unsubscribe(); } }, [])
内容的提问来源于stack exchange,提问作者arthur luna freire
相关产品推荐
相关产品推荐

