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
相关产品推荐
相关产品推荐

