取消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('手动取消请求');
      }
    };
相关推荐
css趣多多20 小时前
地图快速上手
前端
zhengfei61120 小时前
面向攻击性安全专业人员的一体化浏览器扩展程序[特殊字符]
前端·chrome·safari
码丁_11721 小时前
为什么前端需要做优化?
前端
Mr Xu_21 小时前
告别硬编码:前端项目中配置驱动的实战优化指南
前端·javascript·数据结构
Byron07071 天前
从 0 到 1 搭建 Vue 前端工程化体系:提效、提质、降本实战落地
前端·javascript·vue.js
哆啦code梦1 天前
前端存储三剑客:localStorage、sessionStorage与Cookie解析
前端·前端存储
徐小夕@趣谈前端1 天前
Web文档的“Office时刻“:jitword共建版2.0发布!让浏览器变成本地生产力
前端·数据结构·vue.js·算法·开源·编辑器·es6
Data_Journal1 天前
如何使用 Python 解析 JSON 数据
大数据·开发语言·前端·数据库·人工智能·php
德育处主任Pro1 天前
纯前端网格路径规划:PathFinding.js的使用方法
开发语言·前端·javascript
墨笔.丹青1 天前
基于QtQuick开发界面设计出简易的HarmonyUI界面----下
开发语言·前端·javascript