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

React中按钮触发Axios请求时,组件卸载如何取消请求?

处理按钮触发请求的组件卸载取消逻辑

对于按钮点击触发的请求,核心思路是把AbortController实例通过useRef跨渲染周期保存,这样组件卸载时能拿到实例并取消请求,同时还能处理重复点击的情况(避免多个请求并行)。

完整代码示例

import { useRef, useEffect, useState } from 'react';
import axiosPrivate from './your-axios-instance';

function UserProfile() {
  const abortControllerRef = useRef(null);
  const [profileInformation, setProfileInformation] = useState(null);

  // 组件卸载时自动取消未完成的请求
  useEffect(() => {
    return () => {
      abortControllerRef.current?.abort();
    };
  }, []);

  const handleFetchProfile = async () => {
    // 取消之前未完成的请求(可选但实用,防止重复点击导致多请求)
    if (abortControllerRef.current) {
      abortControllerRef.current.abort();
    }

    // 创建新的AbortController并保存到ref
    const controller = new AbortController();
    abortControllerRef.current = controller;

    try {
      const response = await axiosPrivate.get('/user/information', {
        signal: controller.signal,
      });
      setProfileInformation(response.data.user);
    } catch (err) {
      // 忽略AbortError(这是主动取消请求导致的,不属于业务错误)
      if (err.name !== 'AbortError') {
        console.error('请求失败:', err);
      }
    } finally {
      // 请求完成后清空ref,避免卸载时重复执行abort
      abortControllerRef.current = null;
    }
  };

  return (
    <div>
      <button onClick={handleFetchProfile}>加载用户信息</button>
      {profileInformation && (
        <div className="profile">
          <h3>{profileInformation.name}</h3>
          <p>{profileInformation.email}</p>
        </div>
      )}
    </div>
  );
}

关键细节说明

  • 用useRef存控制器:useRef的特性是跨渲染周期保存引用,且修改不会触发组件重渲染,非常适合存储这类临时实例。
  • 组件卸载时清理:通过useEffect的清理函数,在组件卸载时检查ref中是否有未完成的请求控制器,调用abort()阻止后续的state更新。
  • 处理重复点击:每次发起新请求前,先取消之前可能还在pending的请求,避免接口返回顺序混乱或资源浪费。
  • 区分AbortError:主动取消请求会抛出AbortError,这类错误不需要作为业务异常处理,所以在catch里做过滤。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.24 09:20:10