如何在combineReducers中使用root级别的初始状态?

时间:2017-01-21 15:48:13

标签: javascript ecmascript-6 redux

我需要使用单个reducer更新应用程序状态的多个属性。后来我使用了combineReducers redux 帮助程序,它结合了所有的reducer。问题是,除了我需要传递整个状态的那个之外,所有其他的reducers都从状态的根(也就是属性)运行一个级别。

如何使用combineReducers函数传递根状态?

const App = combineReducers({
  pages: combineReducers({
    browse: combineReducers({
      numOfItems: loadMoreItems,
      filter: setFilter
    })
  }),
  <rootState>: openPage,
  favoriteItems: addItemToFavorites,
  inBasketItems: addItemToBasket
})

我在<rootState>放置了什么?

3 个答案:

答案 0 :(得分:1)

如果我理解你的话,你可以定义另一个名为rootState的缩减器,并简单地传递它以将reducer与任何其他缩减器结合使用。

另一方面,如果要使用相同的操作更新多个reducer,只需在每个reducer中添加一个case,操作应该更改状态。

答案 1 :(得分:1)

Redux文档在Structuring Reducers - Beyond combineReducers部分介绍了此主题。基本上,您需要使用 combineReducers来完成您想要的任务。我还举了一个在我最近的博客文章Practical Redux, Part 7: Form Change Handling, Data Editing, and Feature Reducers中编写一些自定义缩减器结构逻辑的例子。

答案 2 :(得分:1)

经过一些重构后,我发现最好不要在这种情况下使用combineReducers。相反,我像这样构建了我的根减速器:

const App = (state = initialState, action) => {
  state = Object.assign({}, state)

  switch (action.type) {
    case OPEN_PAGE:
      state = openPage(state, action)
    case LOAD_MORE_ITEMS:
      state.pages.browse.numOfItems = loadMoreItems(state.pages.browse.numOfItems, action)
    case SET_FILTER:
      state.pages.browse.filter = setFilter(state.pages.browse.filter, action)
    case ADD_ITEM_TO_FAVORITES:
      state.favoriteItems = addItemToFavorites(state.favoriteItems, action)
    case ADD_ITEM_TO_BASKET:
      state.inBasketItems = addItemToBasket(state.inBasketItems, action)
  }

  return state
}

如果任何针对特定部分状态的削减器更复杂,使用combineReducers也许是有意义的,但它对我来说就像这样。为了便于阅读,我仍然在子减速器中保留了一些样板,如下所示:

const loadMoreItems = (state = initialState.pages.browse.numOfItems, action) => {
  switch (action.type) {
    case LOAD_MORE_ITEMS:
      return state = action.number
    default:
      return state
  }
}

所以基本上我保留了状态初始化和动作名称,因为它可以更容易地理解这个减速器的用途。