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-component、redux-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 的某些部分看作数据库,每项类型都有单独的“表”,这样可能可以帮助理解。Normalizr 和 redux-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 来管理对话框和其他弹出窗口、选项卡、扩展面板等是有意义的。

更多信息​

文献