取消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('手动取消请求');
      }
    };
相关推荐
丷丩15 分钟前
MapLibre GL JS第25课:添加栅格瓦片源
开发语言·javascript·gis·mapbox·maplibre gl js
半个落月23 分钟前
彻底搞懂 JavaScript 变量提升(Hoisting)—— 从现象到底层原理
前端·javascript
零度晚风28 分钟前
React 底层原理 & 新特性
前端
用户618482402195129 分钟前
我受够了 Electron 的 IPC 样板代码,于是写了 electron-ipc-auto-import
前端
梦想的颜色44 分钟前
TypeScript 完全指南(中):函数、接口、类与高级类型
前端·typescript
鹏多多1 小时前
OpenSpec+SDD规范驱动AI Agent开发项目实战指南
前端·vue.js·react.js
叶小树咯1 小时前
React 为什么不能像 Vue 那样 state.count++
前端·react.js
ricardo19731 小时前
防抖节流进阶 + requestAnimationFrame:滚动与输入场景的性能优化
前端·面试
wjj不想说话1 小时前
你项目里的 Pinia,可能已经成了第二个 localStorage
前端·vue.js
wuhen_n1 小时前
LangChain JS 入门:快速搭建前端 AI 开发环境
前端·langchain·ai编程