取消axios请求

方案 1:使用 AbortController(推荐,符合标准)

Axios 从 0.22.0 版本开始支持原生 AbortController,替代旧的 CancelToken(已标记为废弃),步骤如下:

javascript 复制代码
import React, { useState, useEffect } from 'react';
import axios from 'axios';

const RequestComponent = () => {
  const [data, setData] = useState(null);
  const [loading, setLoading] = useState(false);

  useEffect(() => {
    // 1. 创建 AbortController 实例
    const controller = new AbortController();
    const signal = controller.signal;

    // 2. 发起请求时传入 signal
    const fetchData = async () => {
      setLoading(true);
      try {
        const res = await axios.get('https://api.example.com/data', {
          signal: signal, // 关联取消信号
        });
        setData(res.data);
      } catch (error) {
        // 3. 捕获取消请求的错误(避免控制台报错)
        if (axios.isCancel(error)) {
          console.log('请求已取消:', error.message);
        } else {
          console.error('请求失败:', error);
        }
      } finally {
        setLoading(false);
      }
    };

    fetchData();

    // 4. 组件卸载/依赖更新时取消请求(useEffect 清理函数)
    return () => {
      controller.abort('组件卸载,取消请求'); // 取消请求并传入提示信息
    };
  }, []);

  return (
    <div>
      {loading ? <p>加载中...</p> : <pre>{JSON.stringify(data, null, 2)}</pre>}
    </div>
  );
};

export default RequestComponent;

方案 2:使用 CancelToken(兼容旧版本)

若项目中 Axios 版本低于 0.22.0,可使用 CancelToken,步骤如下:

javascript 复制代码
import React, { useState, useEffect } from 'react';
import axios from 'axios';

const RequestComponent = () => {
  const [data, setData] = useState(null);
  const [loading, setLoading] = useState(false);

  useEffect(() => {
    // 1. 创建 CancelToken 和取消函数
    const CancelToken = axios.CancelToken;
    let cancel;

    const fetchData = async () => {
      setLoading(true);
      try {
        const res = await axios.get('https://api.example.com/data', {
          cancelToken: new CancelToken((c) => {
            cancel = c; // 保存取消函数
          }),
        });
        setData(res.data);
      } catch (error) {
        if (axios.isCancel(error)) {
          console.log('请求已取消:', error.message);
        } else {
          console.error('请求失败:', error);
        }
      } finally {
        setLoading(false);
      }
    };

    fetchData();

    // 2. 清理函数中执行取消
    return () => {
      if (cancel) cancel('组件卸载,取消请求');
    };
  }, []);

  return (
    <div>
      {loading ? <p>加载中...</p> : <pre>{JSON.stringify(data, null, 2)}</pre>}
    </div>
  );
};

export default RequestComponent;

关键注意事项

  1. 清理时机 :取消请求必须放在 useEffect 的清理函数中,确保组件卸载 / 依赖更新时触发,避免内存泄漏。

  2. 错误捕获 :取消请求会抛出异常,需用 axios.isCancel(error) 判断并过滤,避免控制台报错。

  3. 手动取消 :若需要手动触发(如点击按钮取消),可将 controllercancel 函数存入 useRef,示例:

    ini 复制代码
    const controllerRef = useRef(null);
    
    // 发起请求时
    controllerRef.current = new AbortController();
    
    // 手动取消按钮
    const handleCancel = () => {
      if (controllerRef.current) {
        controllerRef.current.abort('手动取消请求');
      }
    };
相关推荐
Java面试题总结5 分钟前
区间树:反向映射的前置数据结构
java·前端·数据结构
KaMeidebaby9 分钟前
卡梅德生物技术快报|兔单克隆抗体:噬菌体 Fab 免疫文库搭建实操:兔单克隆抗体重组构建完整参数
前端·网络·数据库·人工智能·算法
胡萝卜术9 小时前
从API调用到手写LRU:力扣146「LRU缓存」的哈希表+双向链表终极进化之路
前端·javascript·面试
科技道人9 小时前
记录 默认置灰/禁用 app ‘Search Engine Selector‘ 的disable按钮
开发语言·前端·javascript
天疆说9 小时前
Zotero Connector 在 Edge 里找不到桌面 Zotero(Linux / Zotero 9.0.6 / Edge 150)
linux·前端·edge
李伟_Li慢慢10 小时前
02-从硬件说起WebGL
前端·three.js
kyriewen11 小时前
看了微软几万人用AI编程的数据——效率涨24%的代价没人提
前端·ai编程·claude
2601_9637713711 小时前
How to Scale Your WordPress Store Traffic in 2026
前端·php·plugin
亿元程序员11 小时前
老板说我的3D箭头游戏用来做试玩太普通了,没人想玩,让我变点花样...
前端
李伟_Li慢慢12 小时前
01-threejs架构原理-课程简介
前端·three.js