繁体   English   中英

使用 Redux 工具包异步 REST ZDB974238714CA8DE6FZA 模式时如何捕获 HTTP 4xx 错误?

[英]How to trap HTTP 4xx errors when using Redux Toolkit async REST API pattern?

我已经成功地让我的 React / Redux 应用程序从 REST API 后端检索数据。 我正在使用 Redux Toolkit 的createAsyncThunk功能,该功能会自动设置在 HTTP fetch promise 成功或失败时调用的减速器。

对于这个特定的端点,我希望 Redux 存储在遇到 HTTP 404 Not Found 时反映错误。 目前这还没有发生。 下面显示的组件总是返回“加载成功”。 我怎样才能让它显示“错误”呢?

我了解fetch 无法解决 HTTP 4xx errors 错误,我需要自己检查响应代码并将其解决为失败。 我不明白的是在下面的代码中在哪里或如何做到这一点。 我很难从概念上理解 async/await,我是 Redux Toolkit 的新手,下面的代码已经在努力调整我的大脑。 帮助?

这是我的完整代码:

功能/recipeList/recipeListApi.js

export default async function recipeListApi(localApiKey) {
  const response = await fetch('https://httpstat.us/404');
  const responseJson = await response.json();

  return responseJson;
}

功能/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;

组件/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>}

    </>;
}

检查响应是否具有正常的 state - 或您要检查response的任何条件 - 并返回被拒绝的 promise ,如下所示:

export default async function recipeListApi(localApiKey) {
  const response = await fetch('https://httpstat.us/404');

  if(!response.ok) {
    return Promise.reject();
  }

  return await response.json();
}

如果您的切片 [rejected],则 state.error 应该从 action.error 接收

// features/recipeList/recipeListSlice.js
[fetchRecipeList.rejected]: (state, action) => {
      if (state.loading) {
        state.loading = false;
        state.error = action.error;
      }
    }

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM