嵌套redux存储属性的Redux reducers

时间:2017-04-13 08:28:36

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

我想像这样塑造我的redux商店并添加更多的searchForm兄弟:

import { Map } from 'immutable'

const searchForm = Map(
  {
    'categories': ['meat'],
    'mealTypes': [],
    'location': {
      place: {},
      distanceFromPlaceValue: 10,
      distanceFromPlaceUnit: 'k'
    },
    'keywords': ''
  }
)

const initialState = Map(
  {
    searchForm: searchForm
  }
)

export default initialState

到目前为止,我已经为searchForm的categorieskeywords制作了缩减器,并且正在创建这样的商店:

const reducer = combineReducers({ keywords, categories })
const store = createStore(
  reducer,
  initialState,
  devToolsEnhancer()
)

这会出错:

  

意外的属性“searchForm”在以前的状态中找到了   减速器...

CreateStore需要使用与redux商店的顶级属性匹配的Reducer。是否有办法嵌套商店我如何做和传递减少器没有错误?或者我是否需要更改我的redux商店的形状并让任何减速器成为顶级商店属性?

1 个答案:

答案 0 :(得分:1)

根据Redux初始状态doc:

  

如果您使用combineReducers生成reducer,那么这必须是简单的   与传递给它的键具有相同形状的对象。否则,你   可以自由地传递减速器可以理解的任何东西。

您将combineReducer与keywordcategories密钥配合使用,因此您的初始状态也必须包含此类密钥,但在您的情况下,它仅包含searchForm密钥。

您无需更改状态的形状,只需使用嵌套的combineRedcuers

const reducer = combineReducers({searchForm: combineReducers({ keywords, categories })});

请注意,如果使用Redux combineReducers,则此reducer管理的状态对象必须是普通对象(不是Immutable对象)。 所以我建议这样的事情:

const searchForm = {
    'categories': List(..),
    'mealTypes': List(...),
    'location': Map(...),
    'keywords': ''
}

const initialState =   {
    searchForm: searchForm
};

如果要将Immutable对象用作初始状态,可以使用Redux-Immutable提供combineReducers方法,该方法使用Immutable.js API迭代状态。有关详细信息,请查看此discussion

此外,无论您使用Redux还是Redux-Imuable状态对象(普通或不可变),属性都必须对应于传递给combineReducers的对象的键。