You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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才会生成rejected action,触发对应的Reducer分支。
  • 针对Axios错误的处理能正确提取服务器返回的未授权提示(比如401时的错误信息),而不是只返回通用的错误内容。
  • 修正localStorage的解析逻辑避免了空值解析报错的潜在问题。

内容的提问来源于stack exchange,提问作者verno mbagna

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.07 12:51:00