Skip to main content

状态组织

Redux FAQ:状态组织

我必须把所有状态都放到 Redux 里吗?我是否应该使用 React 的 useStateuseReducer

对此没有“正确”的答案。有些用户喜欢将每一条数据都放入 Redux,以始终维护一个完全序列化且可控的应用状态。另一些人则倾向于将非关键性或 UI 状态(如“这个下拉菜单当前是否打开”)保存在组件的内部状态中。

使用本地组件状态是可以的。作为开发者,确定应用由哪些状态组成,以及每条状态应该放在哪里,是 你的 工作。找到适合你的平衡点,然后坚持下去。

判断何种数据应放入 Redux 的一些常见经验法则:

  • 应用的其他部分是否关心这些数据?
  • 是否需要基于该原始数据创建进一步的派生数据?
  • 这些相同数据是否驱动多个组件?
  • 是否希望能够将该状态恢复到某个时间点(即时间旅行调试)?
  • 是否希望缓存数据(即,如果状态中已有数据,则不重新请求)?
  • 是否希望在热重载 UI 组件时保持数据一致(热重载可能会丢失组件内部状态)?

更多信息

相关文章

讨论

我能把函数、Promise 或其他不可序列化的项放进 store 状态吗?

强烈建议你只往 store 里放普通的可序列化对象、数组和基本类型。_技术上_可以往 store 中插入不可序列化的项,但这样做会破坏持久化和重载 store 内容的能力,还会影响时间旅行调试。

如果你可以接受持久化和时间旅行调试可能无法正常工作,那么完全可以将不可序列化的项放入 Redux store。毕竟,这是 你的 应用,如何实现由你决定。和 Redux 相关的其他许多事情一样,只要你理解所涉及的权衡即可。

更多信息

讨论

我如何组织状态中的嵌套或重复数据?

带有 ID、嵌套或关系的数据通常应以“规范化”的方式存储:每个对象只存储一次,以 ID 作为键,其他引用该对象的地方只存储其 ID,而不是整个对象的副本。将 store 的部分内容视为数据库,按类型划分“表”会有所帮助。像 normalizrredux-orm 这样的库,可以帮你管理规范化数据,并提供抽象。

更多信息

文档

相关文章

讨论

我应该把表单状态或其他 UI 状态放入 store 吗?

决定什么状态放 Redux 的经验法则 同样适用于此问题。

基于这些经验法则,大多数表单状态无需放入 Redux,因为它们大概率不会被多个组件共享。但具体情况依然取决于你和你的应用。你可能会把一些表单状态放入 Redux,因为你正在编辑最初来自 store 的数据,或者确实需要在应用其他组件中看到正在编辑的值。另一方面,保持表单状态在组件内部(本地状态)更简单,用户完成操作后再派发 action 把数据放到 store。

基于此,在大多数情况下,其实不需要基于 Redux 的表单管理库。我们建议按以下顺序尝试:

如果你决定把表单状态放到 Redux,需要考虑性能问题。每次文本输入的击键都派发 action 通常不值得,或许可以考虑用缓冲击键的方式让更改保持本地,然后再派发。一如既往,花些时间分析你应用的整体性能需求。

其他类型的 UI 状态也遵循这些经验法则。典型例子是跟踪 isDropdownOpen 标志。在大多数情况下,应用其他部分不关心这个,所以应该保留在组件状态。但视你的应用情况,也可能合理通过 Redux 来管理弹窗及其他弹出层、标签页、展开面板等。

更多信息

相关文章