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

ReactStrictMode下useSWR+Axios abortController请求被取消问题

问题分析与解决方案

问题根源

React Strict Mode在开发环境中会触发挂载-卸载-重新挂载的组件生命周期,用于检测潜在代码问题。你的自定义钩子中,AbortController在钩子顶层创建,第一次挂载生成的控制器会在Strict Mode触发的“假卸载”阶段被终止;第二次挂载时复用这个已中止的控制器,导致请求直接失败,加上配置了shouldRetryOnError: false,请求不会重新发起。

修复方案

通过useRef跟踪当前活跃的请求控制器,确保每次请求使用全新的控制器,同时保留组件真正卸载时终止请求的功能:

const useRequest = (request: AxiosRequestConfig | null): RequestType => {
  // 用ref跟踪当前活跃的AbortController
  const abortControllerRef = useRef<AbortController | null>(null);

  const fetcher = async (requestFetcher: AxiosRequestConfig | null): Promise<unknown> => {
    // 每次发起请求时创建新的控制器
    const controller = new AbortController();
    abortControllerRef.current = controller;

    try {
      const response = await axios({
        ...requestFetcher,
        signal: controller.signal,
      });
      return response;
    } catch (error) {
      // 捕获请求中止错误,避免SWR将其标记为失败请求
      if (axios.isCancel(error)) {
        return null;
      }
      throw error;
    }
  };

  const {
    data: dataSWR,
    isLoading,
    error
  } = useSWR(
    request && request.method === 'get' ? request.url : null,
    () => fetcher(request),
    {
      revalidateOnFocus: false,
      shouldRetryOnError: false,
    }
  );

  useEffect(() => {
    return () => {
      // 组件卸载时终止当前活跃的请求
      if (abortControllerRef.current) {
        abortControllerRef.current.abort();
        abortControllerRef.current = null;
      }
    };
  }, []);

  return {
    loading: isLoading,
    status: dataSWR ? dataSWR?.status : 0,
    headers: dataSWR ? dataSWR?.headers : null,
    data: dataSWR ? dataSWR?.data.result : null,
    error: error,
  };
};

关键修改点

  • 用useRef存储当前活跃的AbortController,每次调用fetcher时创建新控制器并更新引用,避免Strict Mode下复用已中止的控制器。
  • 在fetcher中捕获请求中止错误并返回null,防止SWR将其判定为失败请求,避免错误状态污染。
  • 清理函数仅终止当前活跃的请求,Strict Mode的假卸载只会终止第一次请求,第二次请求使用新控制器可正常发起。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.11 17:53:23