使用redux-toolkit处理错误

icnyk63a  于 2023-11-19  发布在  其他
关注(0)|答案(4)|浏览(161)

在我的案例中,关于错误的信息深深地存在于响应中,我试图将我的项目移动到redux-toolkit。这是它曾经的样子:

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

字符串
问题是redux-toolkit没有把这些数据放在rejected action creator中,我无法访问错误消息,它把他的消息而不是最初的消息:


的数据
虽然原始的响应看起来像这样:



那么,我如何检索这些数据呢?

ef1yzkbh

ef1yzkbh1#

根据文档,RTK的createAsyncThunk具有默认的错误处理-它将Error示例的序列化版本作为action.error调度。
如果您需要自定义rejected操作中的内容,则由您自己捕获初始错误,并使用rejectWithValue()来决定操作中的内容:

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)
    }
  }
)

字符串

aamkag61

aamkag612#

我们使用thunkAPI,payloadCreator中的第二个参数; * 包含通常传递给Redux形实转换函数的所有参数,以及附加选项 *:对于我们的示例,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的附加选项),您可以在action creator中返回/抛出,以返回具有定义的payload和Meta的rejected响应。它将传递您给予的任何值,并在rejected action的**payload* 中返回它。

y1aodyip

y1aodyip3#

对于那些使用apisauce(使用axios的 Package 器,带有标准化错误+请求/响应转换)
由于apisauce总是解析Promises,所以您可以检查!response.ok并使用rejectWithValue处理它。(注意!,因为我们想检查请求是否notok)

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;
  }
);

字符串

mrwjdhj3

mrwjdhj34#

我的问题是没有立即检测组件中的错误,在await dispatch抛出rejected后。我尝试用我调度的代码try catch,rejectWithValue没有抛出异常。
我发现了一个技巧,我使用了Thunkapi网站文档中的这段代码,它可以让我检测Thunkapi是否抛出异常。

const submitLogin = async ()=>{
    try {
        const resultAction = await dispatch(doLogin({ username, password }));
        const originalPromiseResult = unwrapResult(resultAction)//is needed to throw error
        // console.log("original promise here")
        // console.log(originalPromiseResult)//you can read succees response here, but error goes to the catch
        
        // If login is successful, redirect to the home page
        //do something here like navigate to home
      } catch (rejectedValueOrSerializedError) {
        // Handle login error
        const errorResponse = rejectedValueOrSerializedError//this is the backend api error result
        //handle the error in the ui and do what you need to do
      }
}

字符串

相关问题