【问题标题】:Reapply actions/action history with Redux使用 Redux 重新应用操作/操作历史记录
【发布时间】:2016-04-18 22:19:17
【问题描述】:

我正在使用 Redux(带有 React)来处理我的应用程序中的状态。我有以下情况:

  1. 加载项目列表
  2. 将变换应用于列表(任意数量的变换)
  3. 减少列表中显示的项目
  4. 增加列表中显示的项目

在第 4 步:我如何才能最好地再次增加显示的项目,而第 1 步的转换仍然应用/重新应用?

一个例子:

  1. 加载包含 50 项的列表
  2. 大写项目
  3. 过滤项目以显示少于 4 个字符的项目(=> 导致 30 件)
  4. 再次应用过滤器以显示少于 10 个字符的项目(=> 应导致 50 个项目仍然全部大写)

【问题讨论】:

  • 我能想到的最好的办法是扩展每个列表项,例如(例如大写字母和最多 5 个字符):[{ value: 'text', displayValue: 'TEXT', filtered: false }, { value: 'another text', displayValue: 'ANOTHER TEXT', filtered: true }] 这是解决问题的简单方法,但我想知道惯用的方式是什么。

标签: redux


【解决方案1】:

根据您的描述,应该保存在存储中的唯一实际状态是初始数据和有关当前过滤器的信息。例如,您的状态形状可能如下所示:

{
  items: ['April', 'Jake', 'Mary', 'Zooey', 'Dan'],
  filters: {
    isUppercase: false,
    maxLength: 10
  }
}

当您更改数据时,items reducer 将处理添加和删除项目。当您更改过滤器时,filter reducer 会记录新的过滤器设置。

现在是重要的部分。 实际过滤发生在为组件选择数据时。

我们建议在 Redux 中存储尽可能少的状态。在这种情况下,列表本身和有关过滤器的信息 是最小的可能状态。 应用了过滤器的当前列表总是可以从状态中计算出来的,所以它不应该在状态中

相反,您可以编写一个根据当前状态选择数据的纯函数:

function filterItems(items, filters) {
  return items.filter(item => {
    // return true or false depending on your logic
  })
}

现在,如果你使用 React,你可以在你的 render() 方法中调用它:

var filteredItems = filterItems(this.props.items, this.props.filters)

您可能会发现在每次渲染时重新计算它可能效率低下。幸运的是,解决方案很简单:memoization。确保仅在输入更改时重新计算派生数据。 Reselect 是一个小型库,可以让你做到这一点,它经常与 Redux 一起使用。

您可以在 Redux 网站上的官方 Computing Derived Data 配方和 Reselect README 中找到有关此主题的更多信息以及一些示例。

【讨论】:

    猜你喜欢
    • 2016-10-14
    • 2010-10-23
    • 2023-03-29
    • 2017-12-08
    • 2016-12-04
    • 2023-03-18
    • 2019-07-19
    • 1970-01-01
    • 2020-03-14
    相关资源
    最近更新 更多