React+Redux中登录请求未触发rejected状态,无法更新error状态
问题解决:Redux异步Thunk未触发rejected分支更新错误状态
核心问题
你的代码里,createAsyncThunk的catch块直接返回了错误内容,而没有使用rejectWithValue方法。createAsyncThunk只有通过rejectWithValue抛出错误(或直接抛出异常)时,才会生成rejected类型的action,否则即使捕获了错误,也会被当作fulfilled的结果返回,导致pending状态无法结束,rejected分支永远不会触发。
具体修改步骤
1. 修正authUser异步Thunk的错误处理逻辑
将catch块中的return替换为rejectWithValue,同时正确解析Axios返回的错误信息(包括401未授权这类HTTP错误):
export const authUser = createAsyncThunk( "auth/login", async ({ email, password }: Props, { rejectWithValue }) => { if (typeof email !== "string" || typeof password !== "string") { return rejectWithValue("Email and password are required"); } try { const { data } = await axios({ method: "post", url: "/api/auth/login", headers: { "Content-Type": "application/json" }, data: { email: email.trim(), password: password.trim(), }, }); localStorage.setItem("userInfo", JSON.stringify(data)); return data; } catch (error: unknown) { let errorMessage = "登录失败,请稍后重试"; // 处理Axios请求错误(如401未授权) if (axios.isAxiosError(error)) { errorMessage = error.response?.data?.message || error.message || errorMessage; } else if (typeof error === "object" && error !== null && "message" in error) { errorMessage = (error as { message: string }).message; } // 必须用rejectWithValue返回错误,才能触发rejected分支 return rejectWithValue(errorMessage); } } );
2. 修正状态类型与初始值
- 调整
State类型,让error兼容字符串类型(因为我们返回的是错误信息字符串) - 修正
localStorage解析逻辑,避免getItem返回null时JSON.parse报错:
type State = { loading: boolean; user: IUser | null; error: string | Error | undefined; }; const initialState: State = { loading: false, user: JSON.parse(localStorage.getItem("userInfo") || "null"), error: undefined, };
3. 微调Reducer的rejected分支
确保payload类型匹配修改后的错误返回值:
.addCase(authUser.rejected, (state, { payload }) => { console.log("Auth User Rejected:", payload); state.loading = false; state.error = payload as string; });
为什么这样改?
rejectWithValue是Redux Toolkit规定的异步Thunk抛出错误的标准方式,只有调用它,Thunk才会生成rejectedaction,触发对应的Reducer分支。- 针对Axios错误的处理能正确提取服务器返回的未授权提示(比如401时的错误信息),而不是只返回通用的错误内容。
- 修正
localStorage的解析逻辑避免了空值解析报错的潜在问题。
内容的提问来源于stack exchange,提问作者verno mbagna
相关产品推荐
相关产品推荐

