Skip to main content

Redux 常见问答:组织 State

目录

组织 State

必须将所有的 state 都放入 Redux 吗?应该使用 React 的 setState() 吗?

对此没有“绝对正确”的答案。一些用户喜欢将每一条数据都保存在 Redux 中,以始终维护其应用程序的完全可序列化和受控的版本。其他人更喜欢在组件的内部 state 中保留非关键的或 UI state,例如“此下拉列表当前是否打开”。

使用本地组件 state 是 OK 的。作为开发人员,由你自己决定构成应用程序的 state 类型以及每个 state 应该存在的位置。找到一个适合你的平衡点,并坚持下去。

下面是应该将哪些数据放入 Redux 的一些常见经验法则:

  • 应用程序的其他部分是否关心这些数据?
  • 你是否需要基于这些原始数据创建进一步的派生数据?
  • 是否使用相同的数据来驱动多个组件?
  • 将此 state 恢复到给定的时间点(即时间旅行调试)对你有价值吗?
  • 你是否要缓存数据(即,如果它已经存在,则使用 state 中的内容而不是重新请求它)?
  • 在热重载 UI 组件(交换时可能会丢失其内部 state)时,你需要保持这些数据一致吗?

有许多社区包实现了在 Redux store 中存储每个组件 state 的各种方法,例如 redux-componentredux-react-local 等。也可以按照 this.setState( (previousState) => reducer(previousState, someAction)) 的方式将 Redux 的原理和 reducer 概念应用于更新本地组件 state 的任务中。

更多信息

文献

讨论

相关库

可以将函数、promises 或其他不可序列化的项放入 store state 吗?

强烈建议你只将普通的可序列化对象、数组和原始类型放入 store 中。虽然 技术上 可以将不可序列化的项插入到 store 中,但这样做会破坏 store 内容的持久化和再水化能力,并影响时间旅行调试。

如果你不在意持久性和时间旅行调试等可能无法按预期进行,那么完全可以将不可序列化的项放入 Redux store 中。当然,它是 你的 应用程序,你有最终的决定权。与有关 Redux 的许多其他事情一样,请确保你了解所涉及的权衡利弊。

更多信息

讨论

如何组织 state 中的嵌套或重复数据?

具有 ID、嵌套结构或关系型的数据,通常应以“归一化”方式存储:每个对象应以 ID 为键仅存储一次,其他引用它的对象应仅存储 ID,而不是整个对象的副本。将 store 的某些部分看作数据库,每项类型都有单独的“表”,这样可能可以帮助理解。Normalizrredux-orm 等,这些库可以在管理归一化数据上提供帮助和抽象能力。

更多信息

文档

文献

讨论

应该将表单 state 或其他 UI state 放在 store 中吗?

决定把什么放入 Redux store 的经验法则同样也适用于这个问题。

根据这些经验法则,大多数表单 state 不需要放入 Redux,因为它一般不需要在组件之间共享。但是,最终取决于你和你的应用程序。你可能会选择在 Redux 中保留某些表单 state,因为你需要修改最初来自 store 的数据,或者你需要查看显示在应用程序其他组件中的正在处理的数据。另一方面,将表单 state 保存在组件本地可能要简单得多,并在用户完成表单后才 dispatch action 来将数据放入 store 中。

基于此,在大多数情况下,你可能也不需要基于 Redux 的表单管理库。我们建议你按以下顺序尝试这些方法:

如果你在 Redux 中保存表单 state,你应该花一些时间来考虑性能。对文本框的每次输入变化 dispatch action 也许是没有必要的,你可能需要研究在 dispatch 前缓存输入变化以保存本地更改的方法。与往常一样,你需要花一些时间来分析应用程序的整体性能需求。

其他类型的 UI state 也遵循这些经验法则。经典示例是追踪 isDropdownOpen 标志。在大多数情况下,应用程序的其余部分并不关心它,因此它应该保存在组件 state 里。但是,根据应用程序的实际情况,使用 Redux 来管理对话框和其他弹出窗口、选项卡、扩展面板等是有意义的。

更多信息

文献