React 18严格模式下useIsMounted钩子失效问题求助
React 18严格模式下useIsMounted钩子的修复方案
问题根源
React 18严格模式在开发环境中会执行组件双重挂载/卸载逻辑(用于检测副作用泄漏)。你的原钩子中,useRef的初始值仅在组件首次渲染时赋值,第一次卸载时将isMounted.current设为false,但第二次挂载时未重置该值——因为useRef的初始赋值不会重复执行,导致isMounted.current始终为false,引发异常。
修复方案
调整钩子逻辑,在每次组件挂载时主动重置isMounted的状态,而不是依赖useRef的初始值:
const useIsMounted = (logLabel) => { const isMounted = useRef(false); useEffect(() => { // 挂载时强制设置为true,覆盖之前的状态 isMounted.current = true; if (logLabel) logDev(`useIsMounted ${logLabel} mounted id=${isMounted.current}`); return () => { if (logLabel) logDev(`useIsMounted ${logLabel} un-mounted id=${isMounted.current}`); isMounted.current = false; }; }, [logLabel]); return isMounted; };
关键修复点
- 初始化值设为false:避免首次挂载前状态不确定,后续完全由
useEffect控制状态 - 挂载时主动重置:在
useEffect的挂载回调中明确将isMounted.current设为true,确保无论第一次还是严格模式下的第二次挂载,状态都会正确初始化 - 保持卸载逻辑不变:卸载时依然将状态设为
false,保证异步操作能正确判断组件状态
修复后日志示例
useIsMounted blah mounted id=true useIsMounted blah un-mounted id=true useIsMounted blah mounted id=true
正确处理思路
- 不要依赖
useRef的初始值维护组件生命周期状态:useRef的初始赋值仅在组件首次渲染时执行一次,后续重新挂载不会更新 - 组件挂载状态必须由
useEffect管控:每次挂载时主动初始化状态,卸载时更新状态,确保生命周期的每个阶段状态都准确 - 异步操作前必须检查状态:所有API调用、定时器等异步操作,在更新组件状态前,务必先判断
isMounted.current是否为true,避免组件卸载后执行无效操作
内容的提问来源于stack exchange,提问作者Will59
相关产品推荐
相关产品推荐

