createAsyncThunk的abort()行为异常问题求助
解决Redux Toolkit AsyncThunk取消请求与StrictMode下的错误提示问题
问题根源
- StrictMode双重渲染:开发环境下React StrictMode会触发组件两次挂载,导致
useEffect执行两次,第一次dispatch的请求会被第二次useEffect的清理函数abort。 - 未正确绑定取消信号:原代码未将RTK提供的
signal传递给axios,导致请求未真正取消,且RTK无法正确识别abort状态。 - rejected case未区分abort场景:所有rejected状态都触发错误toast,包括主动取消的请求,导致不必要的错误提示。
解决方案
1. 让Axios请求支持RTK的取消信号
修改blockedUsers异步thunk,将thunkAPI.signal传递给axios,并处理取消错误:
export const blockedUsers = createAsyncThunk( "admin/blocked", async (data, thunkAPI) => { try { const token = thunkAPI.getState().auth.user.token; // 传递RTK的取消信号给Axios,同时传入分页参数 return await axios.get(`${API_URL}/blocked`, { params: data, signal: thunkAPI.signal }); } catch (error) { // 判断是否为主动取消的请求,此类错误无需传递错误信息 if (axios.isCancel(error)) { throw error; // 抛出后RTK会自动标记请求为aborted } // 处理其他业务错误 const message = (error.response?.data?.message) || error.message || error.toString(); return thunkAPI.rejectWithValue(message); } } );
2. 在Reducer中过滤abort类型的rejected请求
修改blockedUsers.rejected的case逻辑,仅处理非主动取消的错误:
.addCase(blockedUsers.rejected, (state, action) => { state.isLoading = false; // 仅当请求不是主动取消时,才设置错误状态和显示提示 if (!action.meta.aborted) { state.isError = true; // 优先使用rejectWithValue传递的payload, fallback到error信息 state.message = action.payload || action.error.message; toast.error( `Could not get blocked users. Reason: ${state.message}`, unsuccessful ); } })
3. 关于生产环境的说明
开发环境下StrictMode的双重渲染是React的调试机制,生产环境中会自动禁用,因此部署后不会出现两次请求的情况,无需额外处理。
效果验证
- 开发环境下:首次请求被abort时,不会弹出错误toast,也不会设置错误状态;第二次请求正常完成,渲染数据。
- 生产环境下:仅发起一次请求,无额外abort操作,正常运行。
内容的提问来源于stack exchange,提问作者Roshan Shetty
相关产品推荐
相关产品推荐

