用于嵌套 redux 存储属性的 Redux reducers

Redux reducers for nested redux store properties

我想像这样塑造我的 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()
)

出现错误:

unexpected property "searchForm" found in previous state by the reducer...

CreateStore 需要采用与 redux 存储的顶级属性匹配的 reducer。有没有办法嵌套我所做的商店并在没有错误的情况下传递减速器?或者我是否需要更改我的 redux 存储的形状并将任何 reducer 设置为顶级存储属性?

根据 Redux 初始状态文档:

If you produced reducer with combineReducers, this must be a plain object with the same shape as the keys passed to it. Otherwise, you are free to pass anything that your reducer can understand.

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

你不需要改变状态的形状,你可以简单地使用嵌套 combineRedcuers:

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

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

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

const initialState =   {
    searchForm: searchForm
};

如果您想使用不可变对象作为初始状态,您可以使用 Redux-Immutable which provides combineReducers method that uses Immutable.js API to iterate the state. Please check this discussion 了解更多详细信息。

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