【问题标题】:returning nested state with redux and thunk使用 redux 和 thunk 返回嵌套状态
【发布时间】:2018-03-02 18:57:11
【问题描述】:

我对 redux 和 thunk 还很陌生,并且一直在按照教程尝试和理解,并且正在设法将它应用到我的应用程序中。我不明白的一件事是,我如何将根级别的多个状态对象放入一个嵌套对象中。例如,现在我的状态如下:

{
  timeline: [Array] // My timeline data in an array of objects
  timelineHasErrored: false,
  timelineIsLoading: false
}

但我真正想要的是:

{
  timeline : {
    data: [Array] // My timeline data in an array of objects
    hasErrored: false,
    isLoading: false
  }
}

我真的不太确定如何嵌套这些,或者这样做的正确方法是什么。下面是我的redux代码,很简单,所以我会全部发布。

减速器指数

import { combineReducers } from 'redux'
import { timeline, timelineHasErrored, timelineIsLoading } from './timeline'

export default combineReducers({
    timeline, timelineHasErrored, timelineIsLoading
});

时间线缩减器

import { TIMELINE_HAS_ERRORED, TIMELINE_IS_LOADING, TIMELINE_FETCH_DATA_SUCCESS } from '../constants/action-types.js'

export function timelineHasErrored(state = false, action) {
  switch (action.type) {
    case TIMELINE_HAS_ERRORED:
      return action.hasErrored;
    default:
      return state;
  }
}

export function timelineIsLoading(state = false, action) {
  switch (action.type) {
    case TIMELINE_IS_LOADING:
      return action.isLoading;
    default:
      return state;
  }
}

export function timeline(state = [], action) {
  switch (action.type) {
    case TIMELINE_FETCH_DATA_SUCCESS:
      return action.timeline;
    default:
      return state;
  }
}

操作

import { TIMELINE_HAS_ERRORED, TIMELINE_IS_LOADING, TIMELINE_FETCH_DATA_SUCCESS } from '../constants/action-types.js'
import api from '../services/api'

export function timelineHasErrored(bool) {
  return {
    type : TIMELINE_HAS_ERRORED,
    hasErrored : bool
  }
}

export function timelineIsLoading(bool) {
  return {
    type : TIMELINE_IS_LOADING,
    isLoading : bool
  }
}

export function timelineFetchDataSuccess(timeline) {
  return {
    type : TIMELINE_FETCH_DATA_SUCCESS,
    timeline
  }
}

export function timelineFetchData() {
  return dispatch => {
    dispatch( timelineIsLoading(true) )

    api.getTracks().then(
      res => {
        dispatch( timelineIsLoading(false) )
        dispatch( timelineFetchDataSuccess(res.body) )
      },
      err => {
        dispatch( timelineIsLoading(false) )
        dispatch( timelineHasErrored(true) )
      }
    )
  }
}

然后在我的反应组件中,我按照我想要的方式格式化对象......但我认为将它嵌套在实际状态会更好,所以如果事情发生变化,我不会为自己创造额外的工作

// Redux State
const mapStateToProps = (state) => {    
  const obj = {
    timeline : {
      data : state.timeline,
      hasErrored: state.tracksHasErrored,
      isLoading: state.tracksIsLoading
    }
  }

  return obj
}

// Redux Dispatch
const mapDispatchToProps = (dispatch) => {
  return {
    fetchData: () => dispatch( timelineFetchData() )
  }
}

如果有人对我有任何提示或更正,请带上他们,我正在努力掌握 redux,谢谢!

【问题讨论】:

    标签: javascript reactjs redux redux-thunk


    【解决方案1】:

    您的时间轴减速器非常小,因此您可以将其作为单个减速器,如下所示:

    const initialState = {
        data: [],
        hasErrored: false,
        isLoading: false
    };
    
    export function timeline(state = initialState, action) {
      switch (action.type) {
        case TIMELINE_HAS_ERRORED:
          return {
             ...state,
             hasErrored: action.hasErrored
          };
    
        case TIMELINE_IS_LOADING:
          return {
             ...state,
             isLoading: action.isLoading
          };
    
        case TIMELINE_FETCH_DATA_SUCCESS:
          return {
             ...state,
             data: action.timeline
          };
    
        default:
          return state;
      }
    }
    

    那么你就不需要调用combineReducers(),除非你有其他的reducer。

    【讨论】:

    • 啊,我明白了,所以一个函数,您只需根据调用的 action.type 替换适用的对象。不过我会有更多的减速器,所以我还能保持我的减速器索引不变吗?我只是导出timeline?而不是我现在的 2 个?
    • 是的,您只需导出您的单个 timeline 减速器,然后在您的根减速器(如果有的话)中您将 combineReducers() 您的 timeline 和任何其他减速器
    猜你喜欢
    • 1970-01-01
    • 2017-10-23
    • 2018-11-16
    • 2018-11-14
    • 2019-12-04
    • 1970-01-01
    • 2018-03-19
    • 1970-01-01
    • 2016-06-20
    相关资源
    最近更新 更多