使用 Redux Toolkit 异步 REST API 模式时如何捕获 HTTP 4xx 错误?
Posted
技术标签:
【中文标题】使用 Redux Toolkit 异步 REST API 模式时如何捕获 HTTP 4xx 错误?【英文标题】:How to trap HTTP 4xx errors when using Redux Toolkit async REST API pattern? 【发布时间】:2020-11-22 11:40:51 【问题描述】:我已成功让我的 React / Redux 应用程序从 REST API 后端检索数据。我正在使用 Redux Toolkit 的 createAsyncThunk 功能,它会自动设置在 HTTP fetch promise 成功或失败时调用的 reducer。
对于这个特定的端点,我希望 Redux 存储在遇到 HTTP 404 Not Found 时反映错误。目前这还没有发生。下面显示的组件总是返回“加载成功”。如何让它显示“错误”?
我了解fetch doesn't resolve with an error on HTTP 4xx errors,我需要自己检查响应代码并将其解决为失败。我不明白的是在下面的代码中在哪里或如何做到这一点。我很难从概念上理解 async/await,我是 Redux Toolkit 的新手,而下面的代码已经在努力调整我的大脑。帮忙?
这是我的完整代码:
features/recipeList/recipeListApi.js
export default async function recipeListApi(localApiKey)
const response = await fetch('https://httpstat.us/404');
const responseJson = await response.json();
return responseJson;
features/recipeList/recipeListSlice.js
import createAsyncThunk, createSlice from "@reduxjs/toolkit";
import recipeListApi from "./recipeListApi";
const sliceName = "recipeList";
const initialState =
loading: false,
error: null,
data: null
;
export const fetchRecipeList = createAsyncThunk("recipeList/fetchRecipeList", async (thunkAPI) =>
const response = await recipeListApi();
return JSON.stringify(response);
);
const recipeListSlice = createSlice(
name: sliceName,
initialState: initialState,
extraReducers:
[fetchRecipeList.pending]: state =>
if (!state.loading)
state.loading = true;
,
[fetchRecipeList.fulfilled]: (state, action) =>
if (state.loading)
state.loading = false;
state.data = action.payload;
,
[fetchRecipeList.rejected]: (state, action) =>
if (state.loading)
state.loading = false;
state.error = action.payload;
);
export const recipeListReducer = recipeListSlice.reducer;
components/RecipeList.js
import React, useEffect from 'react';
import useDispatch, useSelector from 'react-redux';
import fetchRecipeList from '../features/recipeList/recipeListSlice';
export const RecipeList = () =>
const recipeList = useSelector(state => state.recipeList);
const dispatch = useDispatch();
/* Equivalent to componentDidMount() */
useEffect(() =>
dispatch(fetchRecipeList());
, []);
return <>
recipeList.loading && <h1>Loading</h1>
!recipeList.loading && recipeList.error !== null && <h1>Error</h1>
!recipeList.loading && recipeList.error === null && <h1>Loaded successfully</h1>
</>;
【问题讨论】:
这样一个写得很好的问题:) 太糟糕了,这个问题没有答案。我也面临同样的问题。 【参考方案1】:检查响应是否处于正常状态 - 或者您想要检查 response
的任何条件 - 并返回一个被拒绝的承诺,如下所示:
export default async function recipeListApi(localApiKey)
const response = await fetch('https://httpstat.us/404');
if(!response.ok)
return Promise.reject();
return await response.json();
【讨论】:
【参考方案2】:如果你的切片 [rejected],state.error 应该从 action.error 接收
// features/recipeList/recipeListSlice.js
[fetchRecipeList.rejected]: (state, action) =>
if (state.loading)
state.loading = false;
state.error = action.error;
【讨论】:
以上是关于使用 Redux Toolkit 异步 REST API 模式时如何捕获 HTTP 4xx 错误?的主要内容,如果未能解决你的问题,请参考以下文章
Redux工具包 - Redux Toolkit的异步操作(发送网络请求)
使用 react-router-v5 和 redux-toolkit 登录时重定向页面