【问题标题】:React + Redux + normalizr api request error handlingReact + Redux + normalizr api 请求错误处理
【发布时间】:2019-03-05 03:58:00
【问题描述】:

我已经为来自我的应用程序的每个 API 调用实现了一个抽象的“实体”reducer。现在我想使用 normalizr,将 API 数据保持在规范化的形状。到目前为止,我一直在通过 API 操作将来自 API 中间件的 API 请求响应保存在 reducer 中,例如:

case action.type.includes(API_ERROR):
case action.type.includes(API_SUCCESS):
  return {
    ...state,
    [action.payload.label]: {
      error: action.isError,
      data: action.payload.data
    }
  };

保留我的错误标志,以便能够(在组件中)指示请求是否成功。

如果我正确理解了 normalizr,那么实体 reducer 将被视为“数据库”。我想在标准化数据中有 errorisError 标志是不对的,是吗?。

我只是无法解决,当我使用 normalizr 规范化数据时,我的 Reducer 的外观以及在此代码重构之后如果请求成功与否,我将如何跟踪(在组件中...)

另一件事是,如果我的请求失败,响应数据将不包含 ID 或任何其他表明请求失败的标识(我目前使用的实体标签来自,例如 fetchMembers() 行动作为指标)。失败的响应数据仅包含状态和原因(为什么)。

请问大家有什么建议吗?我是否可以继续只使用一个抽象化简器,或者我应该更好地为我的所有 API 操作制作自定义化简器?


SUBQUESTION:

而且我也有请求,在组件的上下文中哪些响应数据不重要,唯一重要的信息是请求成功或失败(注销、登录等请求) )。我假设不应将他们的响应分配给 redux 存储以防止存储膨胀。请问这样的请求我该怎么办?

【问题讨论】:

    标签: reactjs react-native redux react-redux normalizr


    【解决方案1】:

    不要在规范化数据中放置 isError 或 isLoading 标志,因为 normalizr 用于规范化深度嵌套的对象。本质上,它采用深度嵌套的 javascript 对象并将其展平,这样您就可以摆脱冗余数据,这是它的最大优势。 我们使用了 React + Redux-Sagas + normalizr。希望这段代码能帮助你设置你的reducer

    减速器

    // @flow
    
    import {
      FETCH_DETAILED_EXPERIENCE_DATA,
      FETCH_DETAILED_EXPERIENCE_DATA_SUCCESS,
      FETCH_DETAILED_EXPERIENCE_DATA_ERROR,
    } from '../ActionTypes'
    import Immutable from 'seamless-immutable'
    import { createReducer } from '../CreateReducer'
    
    const INITIAL_STATE = Immutable({
      experienceData: null,
      isFetching: false,
      error: null,
    })
    
    const reducers = {
      [FETCH_DETAILED_EXPERIENCE_DATA]: (state, action) => {
        return Immutable.merge(state, { experienceData: null, isFetching: true })
      },
      [FETCH_DETAILED_EXPERIENCE_DATA_SUCCESS]: (state, { data }) => {
        return Immutable.merge(state, { experienceData: data, isFetching: false, error: null })
      },
      [FETCH_DETAILED_EXPERIENCE_DATA_ERROR]: (state, { error }) => {
        return Immutable.merge(state, { error, isFetching: false })
      },
    }
    
    export const reducer = createReducer(INITIAL_STATE, reducers)
    

    传奇

    import { FETCH_DETAILED_EXPERIENCE_DATA } from '../ActionTypes'
    import { put, takeLatest, call } from 'redux-saga/effects'
    import API from '../../Services/baseApi'
    import * as ExperienceActions from './Actions'
    import * as EntitiesActions from '../entities/Actions'
    
    import parseExperienceDetailResponse from 'App/Schemas/APIResponse/ExperienceDetailResponse'
    
    function* fetchExperienceDetails(action) {
      try {
        const response = yield call(API.get, 'URL')
        const { entities, result } = parseExperienceDetailResponse(response.data)
        yield put(EntitiesActions.updateEntities(entities))
        yield put(ExperienceActions.fetchDetailedExperienceSuccess(result))
      } catch (e) {
        yield put(ExperienceActions.fetchDetailedExperienceError(e.message))
      }
    }
    
    export default function* root() {
      yield [yield takeLatest(FETCH_DETAILED_EXPERIENCE_DATA, fetchExperienceDetails)]
    

    架构

    // @flow
    
    import { normalize, schema } from 'normalizr'
    
    const experience = new schema.Entity(
      'experiences',
      {
        owner: user,
      },
      { idAttribute: 'Id' },
    )
    
    
    const response = new schema.Object({
      experience,
    })
    
    export default (input: any) => {
      const { entities, result } = normalize(input, response)
    
      return {
        entities,
        result: result,
      }
    }
    

    希望对您有所帮助,谢谢。

    【讨论】:

    • 你好。首先非常感谢您的回答!无论如何,我试图避免使用 sagas :-( 如果我可以问.. 你如何处理登录或注销之类的请求?你在保存响应数据吗?或者你如何通知组件响应来了?
    • 我们正在调度登录 API 的操作,然后在 componentWillReceiveProps(nextProps){} 中监听响应。这个 Action 的派发会将数据保存在我们可以随时使用的 rootReducer 中。
    • 您还需要坚持您的响应,以便您可以保存您的已登录状态。使用 redux-persist (github.com/rt2zz/redux-persist)。这对我帮助很大。你也可以投票给答案,因为它很有帮助,谢谢。
    猜你喜欢
    • 2021-12-29
    • 2016-05-07
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-11-03
    • 1970-01-01
    • 2021-04-02
    相关资源
    最近更新 更多