提取一个减速器,没有组其他部件(可以处理“其余状态”的减速器)

时间:2016-12-22 09:20:50

标签: redux

假设我想拥有以下状态结构:

{
  deep: { ... },
  foo: 0,
  bar: 0,
  str: ''
}

deep可能很复杂,所以我想为它提取专用的reducer

const deepReducer = (state = {}, action) => { ... }

对于其余部分(foo,bar和str),只需使用另一个reducer,因为它们非常简单

const initialState = { foo: 0, bar: 0, str: '' } // May also need to add deep here
const defaultReducer = (state = initialState, action) => { ... }

但是这个结构似乎不起作用,如果使用combineReducers将其他reducers组合,那么结构将变为:

{
  deep: { ... },
  others: {
    foo: 0,
    bar: 0,
    str: '',
  }
}

但我不想把它们分组,因为他们的关系并不那么强大。

是否有可能在2个减速器中实现 ?或者唯一的解决方案是为每个州(foo,bar和str)创建专用的reducer?

1 个答案:

答案 0 :(得分:1)

我觉得你应该先解决国家管理问题。然后,适当地拆分减速器会更容易。

TLDR 让您的Reducer尽可能简单,并使用状态规范化和选择器的组合,以确保您不会不必要地使您的Reducer复杂化。

州管理

正如文档所述

在顶级对象中组织数据的最常用方法是进一步将数据划分为子树,其中每个顶级键代表相关数据的某些“域”或“切片”。

  

首先,了解整个应用程序实际上只有一个减速器功能非常重要

状态树中的每个叶子(数据切片)都应该有自己的专用reducer。这是因为每个叶子代表分组数据的给定域。将此状态视为数据库。每个叶子代表一个分组数据表。

州规范化

你说你的州有一个深层嵌套的对象。

 {
  deep: { ... },
  foo: 0,
  bar: 0,
  str: ''
}

而不是担心如何围绕这种状态形状构建缩减器,而是在第一种情况下尝试简化状态树。

如果规范化状态,这将降低状态对象中的嵌套级别。因此,减速器不必处理深层次的嵌套,因此更简单。

请记住,编码简单就是美。

<强>选择器

您的州包含应用程序中数据的最小表示。

如果你尽了最大的努力,你的状态中有一个深度嵌套(复杂)的对象,那么你就会使用你的选择器。如果您不使用选择器,那么您的Reducer将需要知道如何从状态中提取信息。这将为减速器添加不必要的逻辑,并使它们膨胀,从而破坏我们的应用程序模块化。

通过使用选择器,我们可以以模块化方式从我们的状态compute derived data,因为选择器可以重复使用和组合。

我们如何使用选择器?

使用我们州的类比作为前端数据库。选择器代表我们提取数据的查询

选择器示例

来自文档的此示例使用流行的reselect库来创建选择器。 在这个例子中,从我们的状态计算的派生数据是实际可见的待办事项。过滤后的列表来自我们所有待办事项列表和当前可见性过滤器列表,可以设置为all,none或enabled。

const getKeyword = (state) => state.keyword

const getVisibleTodosFilteredByKeyword = createSelector(
  [ getVisibleTodos, getKeyword ],
  (visibleTodos, keyword) => visibleTodos.filter(
    todo => todo.text.indexOf(keyword) > -1
  )
)

如果我们没有执行此todo过滤操作,那么我们必须将过滤后的待办事项存储在状态中,并在每次可见性过滤器更改时更新stae。