【问题标题】:Extract one reducer out, without group other parts (a reducer that can handle "the rest states")提取一个减速器,而不将其他部分分组(可以处理“其余状态”的减速器)
【发布时间】:2016-12-22 21:11:20
【问题描述】:

假设我想要以下状态结构:

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

deep 可能很复杂,所以我想为它提取一个专用的减速器

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 会分组其他reducer,那么结构会变成:

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

但我不想将他们归为一类,因为他们的关系并不那么牢固。

有可能在 2 个 reducer 中实现吗?或者唯一的解决方案是为每个状态(foo、bar 和 str)创建一个专用的 reducer?

【问题讨论】:

    标签: redux


    【解决方案1】:

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

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

    状态管理

    如文档所述

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

    首先,重要的是要了解您的整个应用程序实际上只有一个 reducer 函数

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

    状态标准化

    你说你的状态中有一个嵌套很深的对象。

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

    与其担心如何围绕这个状态形状构建你的减速器,我会尝试在第一个实例中简化你的状态树。

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

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

    选择器

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

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

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

    我们如何使用选择器?

    将我们的状态类比为前端数据库。选择器代表我们获取数据的查询

    选择器示例

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

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

    如果我们不执行这个 todo 过滤操作,那么我们将不得不将过滤后的 todos 存储在 state 中,并在每次可见性过滤器更改时更新 stae。

    【讨论】:

      猜你喜欢
      • 2017-07-03
      • 1970-01-01
      • 2019-04-11
      • 2019-04-24
      • 2019-04-20
      • 2021-06-09
      • 2021-07-18
      • 2020-01-23
      相关资源
      最近更新 更多