如何让createAsyncThunk抛出的错误被调用方的.catch捕获?
如何让createAsyncThunk的错误触发调用方dispatch的.catch?
我尝试在createAsyncThunk的axios响应中返回错误,但当axios返回错误时,调用方dispatch的.catch无法触发。我希望将错误抛给调用方,无需在slice中维护单独的error属性——之前用error属性实现过功能,但需要重置、设置错误,比较麻烦,更希望直接通过调用方的.catch处理所有逻辑。
现有代码
cars.store.js
export const getCars = createAsyncThunk( 'cars/getCars', async (payload, { rejectWithValues, dispatch }) => { return axios.get('/cars') .then((res) => res.data)) .catch((err) => rejectWithValues(err)) } ) const cars = createSlice({ name: 'cars', initialState: { loading: false, cars: [] }, reducers: { ... setLoading(state, action) { state.loading = action.payload } }, extraReducers: (builder) => { builder .addCase(getCars.pending, (state) => { state.loading = true }) .addCase(getCars.rejected, (state) => { state.loading = false }) .addCase(getCars.fulfilled, (state, action) => { state.cars = action.payload }) ... } })
调用方代码
useEffect(() => { dispatch(getCars()) .catch((err) => { console.log('This wont print') }) })
解决方法
你使用rejectWithValue的方式会将错误包装为Redux的rejected action,但不会让dispatch返回的Promise进入reject状态,所以调用方的.catch无法触发。要实现需求,需要直接抛出错误,同时可以保留extraReducers中的rejected处理逻辑。
修改后的thunk代码
方式1:使用try/catch直接抛出
export const getCars = createAsyncThunk( 'cars/getCars', async (payload, { dispatch }) => { try { const res = await axios.get('/cars'); return res.data; } catch (err) { // 直接抛出错误,让dispatch的Promise进入catch throw err; } } );
方式2:不手动捕获axios错误
如果不需要在thunk内做额外错误处理,直接返回axios请求的Promise即可,错误会自动向上抛出:
export const getCars = createAsyncThunk( 'cars/getCars', async (payload, { dispatch }) => { const res = await axios.get('/cars'); return res.data; // 不手动catch,axios的错误会被thunk传递给调用方的.catch } );
说明
- 直接抛出错误后,
createAsyncThunk依然会触发getCars.rejectedaction,所以extraReducers中设置loading: false的逻辑依然生效。 - 此时调用方的
dispatch(getCars()).catch()会正常捕获到axios返回的错误,你可以在catch里处理弹窗、日志等逻辑。
内容的提问来源于stack exchange,提问作者jjyj
相关产品推荐
相关产品推荐

