Redux Toolkit+TypeScript中addCase rejected状态未显示问题
问题解决:Redux Toolkit createAsyncThunk 未触发 rejected 状态
你遇到的问题核心是错误处理逻辑不规范,导致createAsyncThunk无法正确识别失败请求,进而把错误当成fulfilled的payload返回,而非触发rejected状态。以下是针对性的修复方案:
1. 规范 createAsyncThunk 的错误处理
axios抛出的错误对象包含大量不可序列化的属性(如config、request),直接传递给rejectWithValue会导致Redux无法判定这是一个失败动作。需要提取可序列化的错误信息,并明确TypeScript类型:
import { AxiosError } from 'axios'; import { createAsyncThunk } from '@reduxjs/toolkit'; // 明确泛型:成功返回类型、参数类型、错误payload类型 export const userRegisterAction = createAsyncThunk< User, User, { rejectValue: string } >( "users/register", async (user: User, { rejectWithValue }) => { try { const response = await axios.post( "http://localhost:5000/api/users/register", user, ); return response.data; } catch (error) { // 类型断言为AxiosError,提取接口返回的错误信息 const axiosError = error as AxiosError<{ message: string }>; const errorMsg = axiosError.response?.data.message || axiosError.message || "注册失败,请稍后重试"; // 传入可序列化的字符串作为错误payload return rejectWithValue(errorMsg); } } );
2. 完善 Slice 的状态处理
你的Slice存在两个关键问题:未统一重置loading状态,未接收rejected的错误payload。修改后:
import { createSlice } from '@reduxjs/toolkit'; // 定义状态类型,规范类型约束 interface UsersState { userAuth: string; registered: User | {}; loading: boolean; error: string; } const initialState: UsersState = { userAuth: "login", registered: {}, loading: false, error: "" }; const usersSlices = createSlice({ name: "users", initialState, reducers: {}, extraReducers: (builder) => { builder .addCase(userRegisterAction.pending, (state) => { state.loading = true; state.error = ""; // 请求开始时清空历史错误 }) .addCase(userRegisterAction.fulfilled, (state, { payload }) => { state.loading = false; state.registered = payload; }) .addCase(userRegisterAction.rejected, (state, { payload }) => { state.loading = false; // 保存错误信息到状态 if (payload) state.error = payload; }); } }); export default usersSlices.reducer;
3. 优化组件调度逻辑(可选)
可以在dispatch后判断请求结果,做针对性提示:
const handleInputSubmit = async (event: React.FormEvent) => { event.preventDefault(); const { firstName, lastName, email, password } = user; if (!firstName || !lastName || !email || !password) { return toast.error( "Please, fill up all inputs !!!", { toastId: "fill_inputs", position: toast.POSITION.TOP_CENTER, autoClose: 1000, } ); } const actionResult = await dispatch(userRegisterAction(user)); // 根据动作结果做后续处理 if (userRegisterAction.fulfilled.match(actionResult)) { toast.success("注册成功!"); } else if (userRegisterAction.rejected.match(actionResult)) { toast.error(actionResult.payload || "注册失败"); } }
完成以上修改后,请求失败时createAsyncThunk会正确触发rejected状态,Redux DevTools中就能看到对应的失败动作,错误信息也会被正确存入状态。
内容的提问来源于stack exchange,提问作者KashimawoJnr
相关产品推荐
相关产品推荐

