You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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;
};

关键修复点

  1. 初始化值设为false:避免首次挂载前状态不确定,后续完全由useEffect控制状态
  2. 挂载时主动重置:在useEffect的挂载回调中明确将isMounted.current设为true,确保无论第一次还是严格模式下的第二次挂载,状态都会正确初始化
  3. 保持卸载逻辑不变:卸载时依然将状态设为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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.12 18:03:24