方案 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;
关键注意事项
-
清理时机 :取消请求必须放在
useEffect的清理函数中,确保组件卸载 / 依赖更新时触发,避免内存泄漏。 -
错误捕获 :取消请求会抛出异常,需用
axios.isCancel(error)判断并过滤,避免控制台报错。 -
手动取消 :若需要手动触发(如点击按钮取消),可将
controller或cancel函数存入useRef,示例:iniconst controllerRef = useRef(null); // 发起请求时 controllerRef.current = new AbortController(); // 手动取消按钮 const handleCancel = () => { if (controllerRef.current) { controllerRef.current.abort('手动取消请求'); } };