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

React严格模式下如何让useEffect清理仅在组件卸载时执行?

解决React严格模式下useEffect清理函数提前执行的问题

React严格模式会触发组件的双重渲染,导致空依赖数组的useEffect清理函数在组件刚挂载时就执行一次,之后卸载时再执行一次。比如你写的这段代码:

useEffect(() => {
    return () => {
        console.log('do you only call once?')
        // TODO: Fix why this is resetting to init state when I ENTER instead of just leave
        // dispatch(resetToInitialState())
    }
}, [])

原本期望清理逻辑只在页面退出时执行,结果刚进入页面就触发了,导致之前设置的状态被提前重置。下面是几种不用关闭严格模式就能解决的方案:

方案1:用Ref标记首次挂载(最稳妥)

利用useRef记录组件是否完成首次挂载,只在真正卸载时执行清理逻辑:

import { useEffect, useRef } from 'react';

// 在组件内部定义
const isMounted = useRef(false);

useEffect(() => {
    // 组件挂载完成后标记
    isMounted.current = true;

    return () => {
        // 只有挂载完成后,才执行目标清理逻辑
        if (isMounted.current) {
            console.log('只在卸载时执行');
            // dispatch(resetToInitialState())
        }
        // 重置标记,避免内存泄漏
        isMounted.current = false;
    };
}, []);

原理:严格模式的第一次渲染会快速执行后卸载,此时isMounted.current还没被设为true,所以跳过清理逻辑;第二次渲染完成后标记为已挂载,当组件真正卸载时,才会执行你需要的操作。

方案2:通过路由监听替代(更贴合业务)

如果你的清理逻辑是为了离开当前页面时重置状态,可以直接监听路由变化,只有当离开当前页面时才执行:

import { useEffect } from 'react';
import { useLocation } from 'react-router-dom';

// 组件内部
const location = useLocation();
const currentPath = '/your-page-path'; // 替换成当前页面的路由路径

useEffect(() => {
    return () => {
        // 检查路由是否离开当前页面
        if (location.pathname !== currentPath) {
            console.log('离开页面时执行');
            // dispatch(resetToInitialState())
        }
    };
}, [location, currentPath]);

这种方式从业务逻辑出发,完全避开了严格模式双重渲染的影响,推荐优先考虑。

方案3:判断严格模式环境(不推荐)

可以通过React内部的环境变量判断是否处于严格模式,但这个变量是非公开的,未来可能失效,仅作参考:

useEffect(() => {
    const isStrictMode = process.env.NODE_ENV === 'development' && window.__REACT_STRICT_MODE__;

    return () => {
        // 非严格模式下才执行
        if (!isStrictMode) {
            console.log('执行清理');
            // dispatch(resetToInitialState())
        }
    };
}, []);

内容的提问来源于stack exchange,提问作者wanna_coder101

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.15 16:11:12