取消路由更改请求 (React/Redux/Axios)
Posted
技术标签:
【中文标题】取消路由更改请求 (React/Redux/Axios)【英文标题】:Cancel requests on route change (React/Redux/Axios) 【发布时间】:2017-12-11 20:12:18 【问题描述】:是否有方便的方法可以使用axios
、redux-thunk
、redux
取消任何路由更改的所有发送请求?我知道axios
有取消令牌,应该添加到每个请求中,我可以调用source.cancel(/* message */)
取消它。
附:目前我在componentWillUnmount
处理这个问题。也许有更好的东西?
【问题讨论】:
【参考方案1】:我发现最简单的方法是将source
存储在状态中,如果请求正在发送,则使用source.cancel
。
componentWillUnmount() if(isLoading) source.cancel()
【讨论】:
但是他们说在 store 中存储函数不是一个好主意。Store 应该是可序列化的。你可以阅读这个here。我也在寻找解决方案。【参考方案2】:非常简单的解决方案是声明isMounted
变量并在组件卸载时将其设置为false
。
处理这个问题的其他方法是,(我不确定axios
但是)XMLHttpRequest
有abort
方法。您可以在componentWillUnmount
上致电xhr.abort()
。
在这里查看:https://developer.mozilla.org/en-US/docs/Web/API/XMLHttpRequest/abort
最后还有一个来自 Netflix UI 工程师的行业解决方案 :)。他们为 RxJS 编写了一个 redux 中间件,并使用 RxJS 操作符来启动和取消请求。
库被称为redux-observable
。我建议看一下示例:https://redux-observable.js.org/docs/recipes/Cancellation.html
你可以在这里观看讨论:https://youtu.be/AslncyG8whg
【讨论】:
【参考方案3】:我找到了一个简单的解决方案(没有 redux)来做到这一点。您只需要在您的 axios 请求中添加一个 cancelToken。之后,使用 useHook 来检测路线变化。然后,在路由卸载时取消带有 TOKEN 的请求,并生成一个新的 TOKEN 来发出新的请求。有关详细信息,请参阅 Axios 文档 (https://github.com/axios/axios)。
Route.tsx 文件
import React, useEffect from 'react';
import Route, RouteProps, useLocation from 'react-router-dom';
import API from 'src/services/service';
const CustomRoute = (props: RouteProps) =>
const location = useLocation();
// Detect Route Change
useEffect(() =>
handleRouteChange();
return () =>
handleRouteComponentUnmount();
;
, [location?.pathname]);
function handleRouteChange()
// ...
function handleRouteComponentUnmount()
API.finishPendingRequests('RouteChange');
return <Route ...props />;
;
export default CustomRoute;
Service.ts 文件
import Response from 'src/models/request';
import axios, AxiosInstance, AxiosResponse from 'axios';
const ORIGIN_URL = 'https://myserver.com'
const BASE_URL = ORIGIN_URL + '/api';
let CANCEL_TOKEN_SOURCE = axios.CancelToken.source();
function generateNewCancelTokenSource()
CANCEL_TOKEN_SOURCE = axios.CancelToken.source();
export const axiosInstance: AxiosInstance = axios.create(
baseURL: BASE_URL,
);
const API =
get<DataResponseType = any>(
endpoint: string,
): Promise<AxiosResponse<Response<DataResponseType>>>
return axiosInstance.get<Response<DataResponseType>>(endpoint,
cancelToken: CANCEL_TOKEN_SOURCE.token,
);
,
// ...Another Functions
finishPendingRequests(cancellationReason: string)
CANCEL_TOKEN_SOURCE.cancel(cancellationReason);
generateNewCancelTokenSource();
,
;
export default API;
【讨论】:
以上是关于取消路由更改请求 (React/Redux/Axios)的主要内容,如果未能解决你的问题,请参考以下文章