如何在ReactJS中使用Axios取消页面跳转时的待处理API请求
解决React页面跳转后取消未完成API请求的问题
问题分析
你遇到的问题本质是浏览器对同一域名的HTTP请求有并发数限制,/userProfile页面的待处理请求占满了可用连接,导致/myTrans页面的请求只能排队等待。核心解决思路是在组件卸载时主动取消这些未完成的请求,释放连接资源。
解决方案:使用AbortController(Axios v0.22.0+推荐)
Axios从v0.22.0开始支持浏览器原生的AbortController接口,这是当前取消请求的标准方案,比旧的CancelToken更可靠。
步骤1:修改API封装,支持接收AbortSignal
修改profile.ts中的API函数,让它们可以接收signal参数并传递给Axios请求:
import axios from "../axios"; export const getClientProfile = async (signal?: AbortSignal) => { try { const respons = await axios.get("/client/profile", { signal }); console.log(" Client Profile respons ", respons.data); return respons.data as ClientProfileModel; } catch (error) { // 捕获取消请求的错误,避免不必要的错误处理 if (axios.isCancel(error)) { console.log("getClientProfile 请求已取消"); } return null; } }; export const getAddtionalInfo = async (target?: any, signal?: AbortSignal) => { try { const respons = await axios.get(`/client/personalDetail?target=${target}`, { signal }); console.log("/client/personalDetail", respons); return respons.data; } catch (error) { if (axios.isCancel(error)) { console.log("getAddtionalInfo 请求已取消"); } return null; } };
步骤2:在组件中管理AbortController,卸载时取消请求
修改UserProfile.tsx中的useEffect,创建AbortController并在组件卸载时调用abort(),同时将signal传递给所有需要取消的API请求:
useEffect(() => { // 创建AbortController实例 const abortController = new AbortController(); const { signal } = abortController; // 调用API时传入signal getClientProfile(signal).then((res) => { setClientProfile(res); }); // 多个API统一用同一个signal,卸载时一起取消 getAddtionalInfo("some-target", signal).then((res) => { // 处理额外信息 }); // 组件卸载时触发取消操作 return () => abortController.abort(); }, []);
原理说明
AbortController是浏览器原生API,调用abort()后,所有绑定了对应signal的请求都会被立即终止。- 组件卸载时,
useEffect的清理函数自动执行,触发请求取消,释放浏览器的HTTP连接资源,让新页面的API请求无需等待旧请求完成即可发送。
旧版本兼容方案(CancelToken)
如果你的Axios版本低于v0.22.0,可以使用旧的CancelToken方案:
步骤1:修改API封装
import axios from "../axios"; export const getClientProfile = async (cancelToken?: axios.CancelToken) => { try { const respons = await axios.get("/client/profile", { cancelToken }); console.log(" Client Profile respons ", respons.data); return respons.data as ClientProfileModel; } catch (error) { if (axios.isCancel(error)) { console.log("getClientProfile 请求已取消"); } return null; } };
步骤2:组件中使用CancelToken
useEffect(() => { const source = axios.CancelToken.source(); getClientProfile(source.token).then((res) => { setClientProfile(res); }); return () => source.cancel("组件卸载,取消请求"); }, []);
内容的提问来源于stack exchange,提问作者kick
相关产品推荐
相关产品推荐

