Redux-ORM 简介
了解 Redux-ORM 作为管理规范化关系数据的抽象层
我们现在已正确搭建了应用的初始结构和 UI 布局,接下来可以开始思考如何构建应用的其余部分。但在开始开发之前,我们需要先绕个弯,介绍一个名为 Redux-ORM 的工具,它将在后续开发中被广泛使用。
Redux-ORM 能够解决许多 Redux 应用中常见的需求,特别是关于在状态中管理规范化的关系型数据。我在自己的项目中大量使用了它,并总结出一些实用的技术和方法,希望这些经验也能对你的项目有所帮助。
为什么要使用 Redux-ORM?
客户端应用经常需要处理嵌套或具有关联关系的数据。对于 Redux 应用,标准建议是将这类数据以“规范化”的形式存储参见 Redux 官方文档中的组织状态部分。这意味着将部分状态结构设计成类似数据库表的形式:每种要存储的实体类型都对应一个对象,作为查找表,通过 ID 映射到具体的数据条目。由于对象本身没有顺序概念,因此需要额外维护一个包含 ID 顺序的数组来表示数据的排列顺序。
注意:有关 Redux 中数据规范化的更多信息,请参考 Redux 文档中的结构化 Reducer章节,尤其是规范化状态结构和更新规范化数据两页内容。
由于数据通常从服务器以嵌套结构返回,必须先转换为规范化形式才能正确加入状态。常见的做法是使用 Normalizr 库完成这一转换。你可以定义数据模式及其关联关系,传入根模式和原始嵌套数据,Normalizr 会返回一个适合合并进状态的规范化数据。
然而,Normalizr 主要用于一次性处理传入的数据,一旦数据进入状态后,它提供的操作支持非常有限。虽然 Normalizr 3.x 已经加入了将数据反规范化回嵌套结构的功能,但并不支持在状态中更新关联数据。
此外,还有许多其他用于管理实体和关系型数据的 Redux 插件参见我的 Redux 生态链表中的实体集合管理部分。其中一些插件能根据 REST 接口或 JSON-API 结构自动获取数据,另一些则提供预设的动作和 reducer 来帮助管理状态中的数据。
Redux-ORM 是一个仅限客户端使用的解决方案,用于定义模型类之间的关系,并作为管理 Redux 状态中规范化关系数据的抽象层。它本身不提供任何数据获取功能。它提供了从状态中选择数据及其关联项的方法,以及创建和更新条目的函数,并在内部自动实现不可变更新,让你无需手动处理不可变性问题。
我与 Redux-ORM 的经历
我早期就接触到了 Redux-ORM,当时我还在学习 Redux,刚开始搭建第一个 React + Redux 的原型应用。Redux-ORM 非常契合我的使用场景,作者 Tommi Kaikkonen 也十分积极回应我的问题,及时修复我报告的 bug,并添加了我提出的一些功能。
自那以后,Redux-ORM 成为了我编写 Redux 应用的核心工具之一。我处理的数据结构复杂且高度嵌套、具有强关联性,而 Redux-ORM 让我能够更轻松地应对这些挑战。尽管目前尚未发布 1.0 版本,但自诞生以来其 API 一直保持稳定一致。值得一提的是,该库自带详实的文档(包括教程和 API 参考),这是一大优势。
我还想补充一点:2017 年初,Tommi 宣布因时间不足无法继续维护 Redux-ORM,并呼吁寻找新的维护者。多位开发者自愿成为“联合维护者”或贡献者,我也在其中。虽然我现在不再专门投入时间开发 Redux-ORM,但我仍关注相关问题和讨论,该库目前仍在积极维护中。
Redux-ORM 与惯用的 Redux
在 Redux 社区中,许多人开发了各种试图在 Redux 上叠加面向对象(OOP)抽象的插件,如我Redux 插件目录中的“变体”页面所示。我多次强调,Redux 的核心理念是函数式编程,而在 Redux 上封装 OOP 层并不符合惯用风格。因此,既然我通常不推荐使用这类库,你可能会问:为什么我却推荐使用 Redux-ORM?它与其他库(如 Jumpsuit 或 Radical)有何不同?
大多数我见过的 OOP 封装方案试图通过将动作创建函数定义为类方法来隐藏细节,往往忽略了多个 reducer 可以响应同一动作的设计(甚至导致这种机制变得不可能)。它们把 Redux 当作需要隐藏的东西,最终丢弃了许多让 Redux 令人喜爱的核心思想。
相比之下,Redux-ORM 并没有试图隐藏 Redux。它不会假装动作常量不存在,也不会认为动作和 reducer 必须是一一对应的关系。它本质上只是为你原本需要手动编写的规范化数据的 CRUD 操作提供了一个抽象层。它让我可以少关注“我需要执行哪些步骤才能正确更新或获取数据”,而更多地专注于从概念层面思考数据本身。
总的来说,我强烈建议在任何需要处理规范化嵌套/关系型数据的 Redux 应用中使用 Redux-ORM。它不会让你完全摆脱对数据管理的思考,但它确实能让这个过程变得更轻松。
基于这一点,让我们现在来了解如何实际使用 Redux-ORM。