Redux 是什么

Redux 是 JavaScript 状态容器,能提供可预测化的状态管理。
它认为:

  • Web 应用是一个状态机,视图与状态是一一对应的。
  • 所有的状态,保存在一个对象里面。

我们先来看看“状态容器”、“视图与状态一一对应”以及“一个对象”这三个概念的具体体现。

Store 是 Redux 中的状态容器,它里面存储着所有的状态数据,每个状态都跟一个视图一一对应。 Redux 也规定,一个 State 对应一个 View。只要 State 相同,View 就相同,知道了 State,就知道 View 是什么样,反之亦然。 所有 State 集合起来成为 “一个对象” 比如,当前页面分三种状态:loading、success 或者 error,那么这三个就分别唯一对应着一种视图。

image.png
那么 Redux 是怎么实现可预测化的呢?我们再来看下 Redux 的工作流程。
image.png

Redux 的设计理念

要明白 Redux 的设计理念,需要先了解 ES、CQRS、Flux 这几个概念。

Redux 是 Flux 思想的一种实现,同时又在其基础上做了改进。 Redux 还是秉承了 Flux 单向数据流、Store 是唯一的数据源的思想。

ES

ES(Event Sourcing ):事件溯源。

  • 不是保存对象的最新状态,而是保存对象产生的事件。
  • 通过事件追溯得到对象最新状态。

    举个例子:我们平常记账有两种方式

    1. 直接记录每次账单的结果
    2. 记录每次的收入/支出,那么我们自己计算的话也可以得到结果

    ES 就是后者

image.png
与传统增删改查关系式存储的区别:

  • 传统的增删是以结果为导向的数据存储,ES 是以过程为导向存储。
  • CRUD 是直接对库进行操作。
  • ES 是在库里存了一系列事件的集合,不直接对库里记录进行更改。

优点:

  • 高性能:事件是不可更改的,存储的时候并且只做插入操作,也可以设计成独立、简单的对象。所以存储事件的成本较低且效率较高,扩展起来也非常方便。
  • 简化存储:事件用于描述系统内发生的事情,我们可以考虑用事件存储代替复杂的关系存储。
  • 溯源:正因为事件是不可更改的,并且记录了所有系统内发生的事情,我们能用它来跟踪问题、重现错误,甚至做备份和还原。

缺点:

  • 事件丢失:因为ES存储都是基于事件的,所以一旦事件丢失就很难保证数据的完整性。
  • 修改时必须兼容老结构:指的是因为老的事件不可变,所以当业务变动的时候新的事件必须兼容老结构。

CQRS

CQRS(Command Query Responsibility Segregation):命令与查询责任分离 ——> 读写分离。
整体的思想是把 Query 操作和 Command 操作分成两块独立的库来维护。
当事件库有更新时,再来同步读取数据库。

  • Query 端,只是对数据库的简单读操作。
  • Command 端,是对事件进行简单的存储,同时通知 Query 端进行数据更新,这个地方就用到了 ES。

image.png
优点:

  • CQ 两端分离,各自独立。
  • 技术代码和业务代码完全分离。

缺点:

  • 强依赖高性能可靠的分布式消息队列。

    Flux

    Flux是一种架构思想,下面过程中,数据总是“单向流动”,任何相邻的部分都不会发生数据的“双向流动”,这保证了流程的清晰。

    Flux 的最大特点,就是数据的“单向流动”。

  1. 用户访问 View。
  2. View 发出用户的 Action。
  3. Dispatcher 收到 Action,要求 Store 进行相应的更新。
  4. Store 更新后,发出一个“change”事件。

image.png

Flux 和 CQRS 的区别

在 CQRS 中,write side 和 read side 分属于两个不同的领域模式,各自的逻辑封装和隔离在各自的 Model 中。
而在 Flux 中,读写业务逻辑都统一封装在 Store 中。

Redux 与 Flux 工作流的差别

  1. Redux 只有一个 Store。
    1. Flux 中允许有多个 Store,但是 Redux 中只允许有一个,相较于 Flux,一个 Store 更加清晰,容易管理
    2. Flux 可有多个 Store 存储应用数据,当 Store 变化的时候再通知 controller-view 更新自己的数据
    3. Redux 将各个 Store 整合成一个完整的 Store,并且可以根据这个 Store 推导出应用完整的 State
  2. Redux 没有 Dispatcher 的概念
    1. Redux 去除了这个 Dispatcher,使用 Store 的Store.dispatch()把 action 传给 Store
    2. 由于所有的 action 处理都会经过这个Store.dispatch()方法,Redux 聪明地利用这一点,实现了与Koa、RubyRack类似的 Middleware 机制
    3. Middleware 可以让你在 dispatch action 后,到达 Store 前这一段拦截并插入代码,可以任意操作 action和 Store。很容易实现灵活的日志打印、错误收集、API请求、路由等操作

      除了以上,Redux 相对 Flux 而言还有以下特性和优点:

      1. 文档清晰,编码统一。
      2. 逆天的 DevTools,可以让应用像录像机一样反复录制和重放。

image.png
image.png

参考资料

《Redux从设计到源码》