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

Redux Toolkit Axios请求:替换rejectWithValue后不进入catch块原因

问题原因说明

参考异步Action代码

"AdminAuthorMentorAuth/login",
async ({ email, password }: LoginI, { rejectWithValue }) => {
  try {
    const user = await api.post(
      "auth/login",
      {
        email,
        password,
      },
      { withCredentials: true }
    );
    if (user.data.check) {
      return { loggedState: true, email: user.data.user.email };
    } else {
      setAxiosToken(user.data.token);
      saveToken(user.data.getToken);
      console.log(user);
      return user.data.user;
    }
  } catch (error: any) {
    console.log(error);
    if (error.response.data) {
      return rejectWithValue(error.response.data.fallbackMessage);
    } else {
      console.log("Error", error);
      return rejectWithValue(error.message);
    }
  }
}
);

组件内Dispatch逻辑代码

try {
  setCurrentStatus(status.loading);
  const res = await dispatch(
    login({ email, password: password.value })
  ).unwrap();
  if (res.loggedState) {
    setCurrentStatus(status.askConfirmation);
    setRequestEmail(res.email);
  }
  if (!res.loggedState) navigate("/");
} catch (error: any) {
  console.log("error", error);
  setCurrentStatus(status.failed);
  setRequestError(error);
}

这个现象是Redux Toolkit中createAsyncThunk和unwrap()的固定执行逻辑导致的,核心规则如下:

  • createAsyncThunk的状态判定规则:传入的异步payload函数,只要执行过程中没有主动抛出错误、没有返回rejectWithValue()的调用结果,无论返回的是业务成功数据还是错误对象,thunk都会将本次请求标记为fulfilled(成功)状态,把返回值作为成功状态的payload。如果在catch分支捕获Axios抛出的原始错误后直接return error,相当于吞掉了原始错误,把错误对象当成正常返回值传给thunk,thunk会判定本次请求执行成功。
  • rejectWithValue的作用:这是createAsyncThunk注入的工具方法,调用后会返回一个特殊标记值,只有payload函数返回这个标记值(或者直接抛出错误),thunk才会将本次请求标记为rejected(失败)状态,把传入rejectWithValue的参数作为失败状态的payload。
  • unwrap()的行为规则:dispatch thunk后调用的unwrap()方法会检查thunk最终状态:如果是fulfilled状态,就直接返回成功的payload,不会抛出错误;如果是rejected状态,才会抛出对应的失败payload,被外层try/catch的catch块捕获。

当把return rejectWithValue(error.message)改成return error时,thunk会把错误对象当成成功payload返回,unwrap()判定状态为成功,直接把error对象赋值给res变量,自然会进入try块执行后续逻辑,不会进入catch分支。如果要让异常进入组件的catch块,除了返回rejectWithValue()的结果,也可以在payload函数的catch分支中直接throw error,同样会触发thunk的rejected状态。


内容的提问来源于stack exchange,提问作者Susant Patel

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.28 04:09:15