[英]Cancel previous fetch request with redux-thunk
Background of the Problem:问题背景:
I am building a React/Redux app that uses redux-thunk and wretch (a fetch wrapper) to handle asynchronous requests.我正在构建一个 React/Redux 应用程序,它使用 redux-thunk 和 wretch(一个获取包装器)来处理异步请求。
I have a few search actions that can vary significantly in their load times, causing undesirable behavior.我有一些搜索操作的加载时间可能会有很大差异,从而导致不良行为。
I have looked into using AbortController(), but it's either cancelling all my requests outright, or failing to cancel the previous request.我曾考虑使用 AbortController(),但它要么彻底取消我的所有请求,要么未能取消前一个请求。
example problem:示例问题:
Goal:目标:
Initiating a request should abort previous pending requests.发起请求应该中止之前的未决请求。
example desired behavior:示例所需的行为:
Code:代码:
actions.js动作.js
The fetchData action gets called via an onClick or by other functions.通过 onClick 或其他函数调用 fetchData 操作。
import api from '../../utils/request';
export function fetchData(params) {
return dispatch => {
dispatch(requestData());
return api
.query(params)
.url('api/data')
.get()
.fetchError(err => {
console.log(err);
dispatch(apiFail(err.toString()));
})
.json(response => dispatch(receiveData(response.items, response.totalItems)))
}
}
export function requestData() {
return {
type: REQUEST_DATA,
waiting: true,
}
}
export function receiveData(items, totalItems) {
return {
type: RECEIVE_DATA,
result: items,
totalItems: totalItems,
waiting: false,
}
}
export function apiFail(err) {
return {
type: API_FAIL,
error: err,
waiting: false,
}
}
utils/request.js实用程序/ request.js
This is wretch import.这是可怜的进口。 Wretch is a fetch wrapper so it should function similarly to fetch.
Wretch 是一个 fetch 包装器,因此它的功能应该与 fetch 类似。
import wretch from 'wretch';
/**
* Handles Server Error
*
* @param {object} err HTTP Error
*
* @return {undefined} Returns undefined
*/
function handleServerError(err) {
console.error(err);
}
const api = wretch()
.options({ credentials: 'include', mode: 'cors' })
.url(window.appBaseUrl || process.env.REACT_APP_API_HOST_NAME)
.resolve(_ => _.error(handleServerError))
export default api;
Attempt:试图:
I've tried using wretch's .signal() parameter with an AbortController(), calling .abort() after the request, but that aborts all requests, causing my app to break.我试过将 wretch 的 .signal() 参数与 AbortController() 一起使用,在请求后调用 .abort() ,但这会中止所有请求,导致我的应用程序中断。 Example below:
下面的例子:
import wretch from 'wretch';
/**
* Handles Server Error
*
* @param {object} err HTTP Error
*
* @return {undefined} Returns undefined
*/
function handleServerError(err) {
console.error(err);
}
const controller = new AbortController();
const api = wretch()
.signal(controller)
.options({ credentials: 'include', mode: 'cors' })
.url(window.appBaseUrl || process.env.REACT_APP_API_HOST_NAME)
.resolve(_ => _.error(handleServerError))
controller.abort();
export default api;
I've tried moving the logic around to various places, but it seems abort all actions or abort none of them.我试过将逻辑移到不同的地方,但它似乎中止所有动作或不中止任何动作。
Any advice as to how to go about this would be appreciated, this is critical for my team.任何有关如何解决此问题的建议将不胜感激,这对我的团队至关重要。
Thank you谢谢
I feel pretty silly right now, but this is what it took to get it working.我现在觉得很傻,但这就是让它工作所需要的。
Solution Steps:解决步骤:
reducer.js减速器.js
export default (state = {
controller: new AbortController(),
}, action) => {
switch (action.type) {
...
signal()
param of the wretch call.signal()
参数中。 actions.js动作.js
export function fetchData(params) {
return (dispatch, getState) => {
const { controller } = getState().reducer;
controller.abort();
const newController = new AbortController();
dispatch(requestData(newController));
return api
.signal(newController)
.query(params)
.url('api/data')
.get()
.fetchError(err => {
console.log(err);
dispatch(apiFail(err.toString()));
})
.json(response => dispatch(receiveData(response.items, response.totalItems)))
}
}
export function requestData(controller) {
return {
type: REQUEST_DATA,
waiting: true,
controller,
}
}
In the reducer, for the case of the requestData action, set the new AbortController to the state.在reducer 中,对于requestData 动作的情况,将新的AbortController 设置为状态。
reducer.js减速器.js
case REQUEST_DATA:
return {
...state,
waiting: action.waiting,
controller: action.controller
};
There's some additional functionality with wretch, an .onAbort()
param, that allows you to dispatch other actions when the request is aborted. wretch 有一些附加功能,一个
.onAbort()
参数,允许您在请求中止时分派其他操作。 I haven't coded that out yet, but I figured I'd include the info for anyone else struggling with this.我还没有把它编码出来,但我想我会为其他任何为此苦苦挣扎的人提供信息。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.