如何在Redux切片的Reducer中取消已派发的Axios请求
解决方案
要在组件卸载时取消Redux Toolkit异步请求,需要将AbortController的signal逐层传递到Axios请求中,具体步骤如下:
1. 修改组件中的useEffect,传递signal给异步Action
在组件的useEffect里创建AbortController,将signal作为参数传给bookDetails action,同时在清理函数中执行abort():
// Component.js import { bookDetails } from '../../features/user/userSlice' useEffect(() => { const abortController = new AbortController(); dispatch(bookDetails({ bookId, signal: abortController.signal })); return () => abortController.abort(); }, [dispatch, bookId])
2. 更新切片中的createAsyncThunk,接收并传递signal
修改bookDetails异步thunk,接收包含id和signal的参数,将signal传入service方法,并处理取消请求的错误:
// userSlice.js import userService from "./userService"; export const bookDetails = createAsyncThunk( "user/book", async ({ bookId: id, signal }, thunkAPI) => { try { const token = thunkAPI.getState().auth.user.token; return await userService.bookDetails({ id, token, signal }); } catch (error) { // 忽略AbortController取消请求的错误 if (error.name === 'CanceledError') { return thunkAPI.rejectWithValue('请求已取消'); } const message = (error.response && error.response.data && error.response.data.message) || error.message || error.toString(); return thunkAPI.rejectWithValue(message); } } );
3. 调整service中的请求,加入signal配置
在service的bookDetails方法中,将signal添加到Axios的请求配置里:
// userService.js const bookDetails = async ({ id, token, signal }) => { const config = { headers: { Authorization: `Bearer ${token}`, }, signal, // 加入signal参数 }; const response = await axios.get(API_URL + `/book/${id}`, config); return response.data; };
当组件卸载时,useEffect的清理函数会调用abortController.abort(),Axios会立即取消请求,同时thunk里会捕获到CanceledError,避免将取消操作当成普通错误处理,从而避免内存泄漏。
内容的提问来源于stack exchange,提问作者Roshan Shetty
相关产品推荐
相关产品推荐

