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

如何清理useEffect外的函数?React定时器内存泄漏修复

解决React组件卸载后定时器导致的状态更新警告

问题根源是组件卸载后,setInterval和setTimeout仍在执行,尝试更新已卸载组件的状态,触发内存泄漏警告。要解决这个问题,你需要用useRef存储定时器ID,再通过useEffect的清理函数在组件卸载时清除定时器,同时处理重复点击的情况。

具体修改步骤:

  1. 添加定时器引用:新增两个useRef来保存定时器ID,方便后续清理:
const time = useRef(30);
const intervalRef = useRef(null);
const timeoutRef = useRef(null);
  1. 修改disableResendBtn函数:将定时器ID存入ref,同时每次点击前先清除之前的定时器(避免重复触发):
function disableResendBtn() {
    // 先清除之前未完成的定时器
    if (intervalRef.current) clearInterval(intervalRef.current);
    if (timeoutRef.current) clearTimeout(timeoutRef.current);

    time.current = 30;
    setsendCodeBtnDisabled(true);
    setsendCodeBtnText(`${i18n.t('RESEND')}(${time.current})`);

    intervalRef.current = setInterval(() => {
        time.current -= 1;
        setsendCodeBtnText(`${i18n.t('RESEND')}(${time.current})`);
        console.log(time.current);
    }, 1000);

    timeoutRef.current = setTimeout(() => {
        setsendCodeBtnDisabled(false);
        setsendCodeBtnText(i18n.t('RESEND'));
        clearInterval(intervalRef.current);
        // 清理引用
        intervalRef.current = null;
        timeoutRef.current = null;
    }, 30000);
}
  1. 添加useEffect清理函数:监听组件卸载事件,清除所有未完成的定时器:
useEffect(() => {
    return () => {
        if (intervalRef.current) clearInterval(intervalRef.current);
        if (timeoutRef.current) clearTimeout(timeoutRef.current);
    };
}, []);

关键说明:

  • 用useRef存储定时器ID是因为ref的.current属性在组件生命周期内保持不变,能在useEffect的清理函数中访问到。
  • 每次点击按钮前清除旧定时器,防止多次点击导致多个定时器同时运行,造成状态混乱。
  • 组件卸载时,useEffect的返回函数会自动执行,清除所有未完成的异步任务,避免状态更新到已卸载的组件上。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.12 19:25:29