使用 redux-toolkit 处理错误

Handling errors with redux-toolkit

有关我案例中的错误的信息在响应中有很深的含义,我正在尝试将我的项目移至 redux-toolkit。过去是这样的:

catch(e) {
  let warning
  switch (e.response.data.error.message) { 
    ...
  }
}

问题是 redux-toolkit 没有将该数据放入 rejected 操作创建者中,我无权访问错误消息,而是将他的消息而不是最初的消息:

虽然原始响应如下所示:

那么我该如何检索该数据?

根据文档,RTK 的 createAsyncThunk 具有默认的错误处理方式 - 它将 Error 实例的序列化版本分派为 action.error

如果您需要自定义进入 rejected 操作的内容,您可以自己捕获初始错误,并且 use rejectWithValue() to decide what goes into the action:

const updateUser = createAsyncThunk(
  'users/update',
  async (userData, { rejectWithValue }) => {
    const { id, ...fields } = userData
    try {
      const response = await userAPI.updateById(id, fields)
      return response.data.user
    } catch (err) {
      if (!err.response) {
        throw err
      }

      return rejectWithValue(err.response.data)
    }
  }
)

对于那些使用 apisauce 的人(使用带有标准化错误的 axios 的包装器 + request/response 转换)

因为 apisauce 总是 resolve Promise,你可以检查 !response.ok 并用 rejectWithValue 处理它。 (注意 ! 因为我们要检查请求是否 not ok)

export const login = createAsyncThunk(
  "auth/login",
  async (credentials, { rejectWithValue }) => {
    const response = await authAPI.signin(credentials);
    if (!response.ok) {
      return rejectWithValue(response.data.message);
    }
    return response.data;
  }
);

我们使用thunkAPI,payloadCreator中的第二个参数; 包含通常传递给 Redux thunk 函数的所有参数,以及其他选项:对于我们的示例,async(obj, {dispatch, getState, rejectWithValue, fulfillWithValue}) 是我们的 payloadCreator 和所需的参数;

这是使用 fetch api

的示例
import { createSlice, createAsyncThunk } from "@reduxjs/toolkit";

export const getExampleThunk = createAsyncThunk(
    'auth/getExampleThunk',
    async(obj, {dispatch, getState, rejectWithValue, fulfillWithValue}) => {
        try{
            const response = await fetch('https://reqrefs.in/api/users/yu');
            if (!response.ok) {
                return rejectWithValue(response.status)
            }
            const data = await response.json();
            return fulfillWithValue(data)
        }catch(error){
            throw rejectWithValue(error.message)
        }
    }
)   

切片中的简单示例:

const exampleSlice = createSlice({
    name: 'example',
    initialState: {
        httpErr: false,
    },
    reducers: {
        //set your reducers
    },
    extraReducers: {
        [getExampleThunk.pending]: (state, action) => {
            //some action here
        },
        [getExampleThunk.fulfilled]: (state, action) => {
            state.httpErr = action.payload;
        },
        [getExampleThunk.rejected]: (state, action) => {
            state.httpErr = action.payload;
        }
    }
})

处理错误

注意: rejectWithValue - 实用程序(来自 thunkAPI 的附加选项),您可以在您的操作创建者中 return/throw 到 return 具有定义的有效负载和元的拒绝响应。它会传递你给它的任何值,并在被拒绝操作的 payload 中传递 return 它。