菜单

规范化和状态结构

相关源文件

本页解释了如何在 Redux 应用程序中正确构建和规范化数据,以提高性能、简化数据管理并实现高效更新。规范化是管理 Redux store 中复杂关系数据的关键技术,尤其是在处理相互引用的项目集合时。

有关选择器和从状态派生数据的信息,请参阅选择器和记忆化。有关常见中间件模式的信息,请参阅中间件模式

什么是规范化?

规范化是一种借鉴自数据库设计的技术,它以以下方式组织数据:

  1. 消除重复数据
  2. 为每种类型的实体创建单一数据源
  3. 使用引用(ID)而不是嵌套来表示数据之间的关系

在 Redux 应用程序中,规范化状态有助于高效管理关系数据、避免重复并简化对单个项目的更新。

来源

为什么要规范化状态?

规范化您的 Redux 状态具有多项显著优势:

  1. 一致性:确保每个实体只有一个副本,无需在多个地方更新相同的数据
  2. 性能:通过避免深层嵌套并实现有针对性的更新,使更新更高效
  3. 可预测性:通过处理更扁平的结构来简化 reducer 逻辑
  4. 更轻松的关系管理:使实体之间关系的表示和更新变得简单明了
  5. 优化:在选择数据时实现更有效的记忆化

如果没有规范化,处理关系数据的应用程序通常难以保持嵌套数据副本的同步,从而导致错误、性能问题和不必要的复杂性。

来源

基本规范化原则

适当规范化的 Redux 状态遵循以下原则:

  1. 每种类型的实体在状态中都有自己的“表”
  2. 每个“表”将项目存储为以 ID 为键的对象
  3. 对单个项目的任何引用都是通过存储项目的 ID 完成的
  4. ID 数组用于指示排序

例如,您将拥有:

这种结构使得查找特定实体、单独更新它们以及维护不同实体类型之间的关系变得简单明了。

来源

使用 Redux Toolkit 实现规范化状态

Redux Toolkit 提供了 createEntityAdapter,这是一个有助于实现规范化状态的实用工具,并包含用于常见操作的预构建 reducer 和 selector。

创建实体适配器

适配器提供了一种标准化方式来存储规范化数据:

  1. 一个 ids 数组,包含所有实体 ID 并按所需顺序排列
  2. 一个 entities 对象,用于存储实体数据,其中 ID 作为键

使用实体适配器的初始状态

这会创建一个具有以下结构的状态:

在 Reducer 中使用实体适配器

适配器提供了用于更新规范化状态的 CRUD 方法

使用实体适配器选择器

适配器还会生成选择器函数,用于从 store 中检索数据

这些选择器可以在组件中与 useSelector 一起使用

来源

规范化状态的数据流

在使用规范化状态的 Redux 应用程序中,数据流通常遵循以下模式:

  1. API 数据传入(通常为嵌套格式)
  2. 数据被规范化(在异步 thunk 或 reducer 中)
  3. 规范化数据存储在 Redux 状态中
  4. 组件通过理解规范化结构的选择器访问数据
  5. 对实体的更新使用实体适配器方法来保持规范化

来源

从嵌套状态转换为规范化状态

当从嵌套状态结构迁移到规范化结构时,您需要转换状态并更新组件逻辑。以下是转换的基本示例:

之前:嵌套数组状态

之后:使用实体适配器的规范化状态

这种转换需要在您的代码库中进行更改,但会使应用程序更易于维护且性能更佳。

来源

使用记忆化选择器优化规范化状态访问

处理规范化数据时,您通常需要派生重构实体之间关系的信息。使用记忆化选择器有助于优化此过程:

记忆化版本仅在 posts 或 userId 更改时重新计算,避免了不必要的重复计算。

规范化数据的常见选择器模式

  1. 按 ID 查找:使用生成的 selectById 选择器
  2. 过滤列表:创建基于条件过滤的记忆化选择器
  3. 连接/反规范化数据:组合来自多种实体类型数据的选择器
  4. 排序数据:根据特定字段排序数据的选择器

来源

规范化状态的最佳实践

  1. 使用实体适配器:Redux Toolkit 的实体适配器为您处理大部分规范化工作
  2. 基于 ID 的引用:始终将实体之间的引用存储为 ID,而不是嵌套对象
  3. 分离实体类型:在您的状态中,将不同类型的实体保存在单独的“表”中
  4. 记忆化选择器:对派生数据使用 createSelector 以避免不必要的重复计算
  5. 保持状态最小化:存储最少所需数据,并在选择器中派生额外值
  6. 一致的 ID 类型:在整个应用程序中使用一致的 ID 类型(字符串或数字)
  7. 多个 ID 数组:考虑为不同的过滤/排序视图使用多个 ID 数组

来源

在规范化状态中处理关系

处理实体之间的关系时,可以使用几种模式:

一对多关系

多对多关系

请记住,在更新过程中可能需要在多个地方维护关系数据,以确保一致性。

来源

结论

规范化 Redux 状态结构是一种最佳实践,可以显著提高应用程序的可维护性和性能。通过将每种类型的数据存储在自己的“表”中并使用引用而不是嵌套,您可以创建更高效、更一致且更易于更新的状态结构。

Redux Toolkit 的 createEntityAdapter 提供了一种实现规范化状态的标准化方法,其中包含用于处理常见操作的内置 reducer 和选择器。

正确实施后,规范化状态将使您的 Redux 应用程序更具可伸缩性、更易于调试,并能更好地处理复杂的数据关系。

来源