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

ReactJS与Router DOM:useEffect中setInterval内存泄漏及路由切换仍运行问题

解决React中setInterval内存泄漏与路由切换后定时器未停止的问题

你的问题根源有两个:一是用状态变量存储定时器ID时,因状态更新异步导致清理函数拿不到正确的ID;二是组件卸载后,未完成的异步请求仍尝试更新状态,引发内存泄漏。以下是可行的解决方法:

1. 用useRef存储定时器ID(核心修复)

状态变量的更新是异步的,在useEffect的清理函数中无法获取到最新的定时器ID。而useRef的.current属性是同步更新的,能确保清理时拿到正确的定时器ID。

import { useEffect, useRef } from 'react';

function DataFetchingComponent() {
  const timerRef = useRef(null);

  const fetchFunction = async () => {
    try {
      const res = await fetch('你的数据接口URI');
      const data = await res.json();
      // 处理获取到的数据,比如更新组件状态
    } catch (err) {
      console.error('数据请求失败:', err);
    }
  };

  useEffect(() => {
    // 启动定时器并把ID存入ref
    timerRef.current = setInterval(fetchFunction, 30000);

    // 组件卸载时清除定时器
    return () => {
      clearInterval(timerRef.current);
    };
  }, []); // 空依赖数组保证只在挂载时执行一次

  return (
    // 组件的JSX内容
  );
}

2. 阻止已卸载组件的状态更新(避免内存泄漏)

即使定时器被清除,正在pending的异步请求可能仍会完成,此时若尝试更新已卸载组件的状态,会引发内存泄漏。添加一个挂载状态标志位即可解决:

import { useEffect, useRef } from 'react';

function DataFetchingComponent() {
  const timerRef = useRef(null);
  const isMounted = useRef(true); // 标记组件是否处于挂载状态

  const fetchFunction = async () => {
    if (!isMounted.current) return; // 组件已卸载,直接终止请求逻辑

    try {
      const res = await fetch('你的数据接口URI');
      const data = await res.json();
      
      if (isMounted.current) { // 再次检查,避免请求过程中组件卸载
        // 在这里更新组件状态,比如setData(data)
      }
    } catch (err) {
      console.error('数据请求失败:', err);
    }
  };

  useEffect(() => {
    timerRef.current = setInterval(fetchFunction, 30000);

    return () => {
      isMounted.current = false; // 卸载时标记为未挂载
      clearInterval(timerRef.current); // 清除定时器
    };
  }, []);

  return (
    // 组件的JSX内容
  );
}

3. 路由切换时的自动清理

当使用React Router切换页面时,当前组件会被React自动卸载,此时useEffect的返回清理函数会被触发,自动执行定时器清除和挂载状态标记,彻底停止定时任务和后续的异步操作。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.21 18:13:24