如何正确使用Redux Toolkit处理登录请求失败的返回信息?
问题
使用Redux Toolkit处理登录请求时,输入正确邮箱密码可正常获取结果,但输入随机值时无法拿到后端返回的404错误信息:
- 触发
authService.rejected分支时,action.payload为空 - 给axios添加catch后,错误信息会进入
fulfilled分支,导致因找不到jwt字段抛出新错误
相关代码
Slice 代码
import { authService } from "../services/AuthService"; export const AuthSlice = createSlice({ name: "weather", initialState: { authStatus: "idle", jwt: "", messageCode: "", }, reducers: {}, extraReducers: (builder) => { // Auth Controller builder .addCase(authService.pending, (state) => { state.authStatus = "loading"; }) .addCase(authService.fulfilled, (state, action) => { console.log("fullfiled", action); const { data: { code, message_code, result: { jwt }, }, } = action.payload; state.messageCode = message_code; state.jwt = jwt; state.authStatus = "succeeded"; }) .addCase(authService.rejected, (state, action) => { console.log("rejected", action.payload); state.authStatus = "failed"; }); }, }); export default AuthSlice.reducer;
Service 代码
import axios from "axios"; export const authService = createAsyncThunk( "authController/auth", async (auth) => { const data = await axios({ method: "post", url: "example.url", headers: {}, data: { email: auth.email, password: auth.password, }, }); return data; } );
后端返回说明
- 登录失败(随机邮箱密码):返回
{ "code": 0, "message": "User not found.", "message_code": "LOGIN_ERROR" },HTTP状态码404 - 登录成功:返回
{code:1,message_code:"LOGIN_SUCCESS",result:{jwt:"token here"}}
最优处理方案
方案一:在rejected分支获取后端错误信息(推荐)
axios遇到4xx/5xx状态码会抛出错误,错误对象的response.data就是后端返回的错误内容。只需在createAsyncThunk中捕获错误,用rejectWithValue抛出错误数据,即可在rejected分支中获取:
修改Service代码:
import axios from "axios"; import { createAsyncThunk } from "@reduxjs/toolkit"; export const authService = createAsyncThunk( "authController/auth", async (auth, { rejectWithValue }) => { try { const data = await axios({ method: "post", url: "example.url", headers: {}, data: { email: auth.email, password: auth.password, }, }); return data; } catch (error) { // 取出后端返回的错误数据 if (error.response?.data) { return rejectWithValue(error.response.data); } // 无后端数据时返回通用错误标识 return rejectWithValue({ message_code: "UNKNOWN_ERROR" }); } } );
修改Slice的rejected分支:
.addCase(authService.rejected, (state, action) => { console.log("rejected", action.payload); state.messageCode = action.payload.message_code; state.authStatus = "failed"; });
方案二:在fulfilled分支统一处理(不推荐)
仅当后端无论成功失败都返回200状态码时才建议使用此方案。需修改axios配置使其不抛出4xx错误,再通过返回的code判断状态:
修改Service代码:
export const authService = createAsyncThunk( "authController/auth", async (auth) => { // 配置validateStatus,仅5xx状态码抛出错误 const data = await axios({ method: "post", url: "example.url", headers: {}, data: { email: auth.email, password: auth.password, }, validateStatus: (status) => status >= 200 && status < 500 }); return data; } );
修改Slice的fulfilled分支:
.addCase(authService.fulfilled, (state, action) => { console.log("fullfiled", action); const { data } = action.payload; state.messageCode = data.message_code; state.authStatus = data.code === 1 ? "succeeded" : "failed"; // 仅登录成功时设置jwt if (data.code === 1) { state.jwt = data.result.jwt; } });
内容的提问来源于stack exchange,提问作者furkan lebit
相关产品推荐
相关产品推荐

