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

使用自定义useFetch请求数据时触发组件卸载后无法更新React state警告如何修复

修复方案

问题根因

这个警告是因为请求未完成时使用该Hook的组件已经卸载,请求返回后仍尝试执行状态更新操作,属于典型的异步任务未清理导致的内存泄漏问题。

修复方法(推荐:直接取消未完成请求)

利用Axios支持的AbortController接口,在useEffect的清理函数中主动取消未完成的请求,从根源避免后续的状态更新操作,同时还能节省无用的网络开销。
修复后的完整代码如下:

import { useState, useEffect } from "react";
import axios from "axios";
const useFetch = (url) => {
  const [data, setData] = useState(null);
  const [error, setError] = useState(null);

  useEffect(() => {
    // 实例化AbortController用于控制请求取消
    const controller = new AbortController();

    axios
      .get(url, {
        // 绑定signal到当前请求
        signal: controller.signal
      })
      .then((response) => {
        setData(response.data);
      })
      .catch((err) => {
        // 排除主动取消请求导致的错误,不需要处理
        if (!axios.isCancel(err)) {
          setError(err);
        }
      });
    
    // useEffect清理函数,组件卸载时执行
    return () => {
      // 主动取消未完成的请求
      controller.abort();
    }
  }, [url]);

  return { data, error };
};

export default useFetch;

替代方案:挂载状态标记

如果你不需要主动取消请求,只需要避免给卸载的组件更新状态,可以通过挂载标记判断是否执行状态更新:

import { useState, useEffect } from "react";
import axios from "axios";
const useFetch = (url) => {
  const [data, setData] = useState(null);
  const [error, setError] = useState(null);

  useEffect(() => {
    // 标记组件是否处于挂载状态
    let isMounted = true;

    axios
      .get(url)
      .then((response) => {
        // 仅组件挂载时才更新状态
        if (isMounted) {
          setData(response.data);
        }
      })
      .catch((err) => {
        if (isMounted) {
          setError(err);
        }
      });
    
    return () => {
      // 组件卸载时修改标记
      isMounted = false;
    }
  }, [url]);

  return { data, error };
};

export default useFetch;

注意:该方案仅规避了状态更新的警告,没有取消未完成的请求,仍会占用网络资源,优先推荐第一种方案。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.30 18:18:00