精益 React 学习指南 (Lean React)- 1.6 Flux

书籍完整目录javascript

1.6 flux

图片描述

这一节将介绍 React 的核心应用架构模式 Flux,包括内容:前端

  • Flux 介绍java

  • MVC 架构之痛git

  • Flux 的理解github

  • Flux 相关库和工具介绍编程

  • Flux 与 React 实例redux

最后咱们将会把以前的 TODOMVC 改成 Flux 的架构。segmentfault

1.6.1 Flux 介绍

简单来说,Flux 是 Facebook 引入到 React 中的一种前端架构,经过定义其核心单向数据流的方式,让 React 应用更加健壮。同时,这种应用架构也具备普适性,能够应用到其余任意前端项目中,甚至能够应用到客户端应用开发中,也就是说 Flux 更应该叫作一种架构模式(Pattern)。后端

1.6.2 MVC 架构之痛

在详细介绍 Flux 以前,咱们先来看看传统的前端 MVC 架构以及其带来的问题。架构

MVC 的实现可能有不少种方式,比较灵活,但基本本质不会改变,只是三者间的数据传递方向可能会改变,即使是 MVP 模式也只是 MVC 的变种,因此为了统一咱们且如下图的 MVC 方式来讨论。

图片描述

概念

  • Model: 负责保存应用数据,和后端交互同步应用数据

  • View: 负责渲染页面 HTML DOM

  • Controller: 负责链接 View 和 Model , Model 的任何改变会应用到 View 中,View 的操做会经过 Controller 应用到 Model 中

  • 关系:Model, View, Controller 都是多对多关系。

流程

以 TODOMVC 为例子用户添加一个 todo 的交互流程:

View -> Action -> Controller -> Model -> View

  1. View -> Action: 添加按钮事件或者 input 输入的提交事件

  2. Action -> Controller: 控制器响应 View 事件

  3. Controller -> Model: 控制器依赖 Model, 调用 Model 添加 todo

  4. Model -> View: View 监听 Model 的改变添加 todo 事件,在 HTML 中添加一个新的 Todo 视图

问题

对于新增一个 todo ,须要编写一个视图渲染处理函数,函数内添加新项目到列表中。同理对于删除一个 todo,也会有一个处理函数。当业务逻辑变多事后,可能有不少模型须要作增删改的功能,与之对应的就是咱们须要精心构建这么多的渲染处理函数。 这种局部更新模式是高性能的关键所在,但问题是:

  1. 更新逻辑复杂,须要编写大量的局部渲染函数

  2. 问题定位困难,页面的当前状态是有数据和这些局部更新函数肯定的

如何解决

若是渲染函数只有一个,统一放在 App 控制器中,每次更新重渲染页面,这样的话:

  1. 任何数据的更新都只用调用重渲染就行

  2. 数据和当前页面的状态是惟一肯定的

重渲染也有弊端,会带来严重的性能问题,重渲染和局部渲染各有好坏,对 MVC 来讲这是一个两难的选择,没法作到鱼和熊掌兼得。

那如何才能兼顾两种模式的优势?

1.6.3 Flux 架构

经过 React + Flux 就能够完美解决 MVC 的问题。

  1. 重渲染: 在 React 中每次渲染都是重渲染,且不影响页面性能,是由于重渲染的是 Virtual Dom。这就意味着彻底不用去关系重渲染问题,增删改的渲染都和初始化渲染相同入口

  2. 数据和状态一致性: Store 的数据肯定应用惟一的状态

简单来讲在 Flux 架构中直接剥离了控制器层,MVC 架构变成了 MV + Flux 架构。

概念

单向数据流

图片描述

这是 Flux 架构的核心思想,重上面的图中能够看到,数据的流向从action 到 view 的一个单向流。

Action

图片描述

Action 能够理解为对应用数据修改的指令,任何修改应用数据的行为都必须需经过触发 action 来修改。Action 能够来自于 View,也能够来自服务端的数据更新。

Action Creator

图片描述

为了抽象 Action ,提供一些辅助的语义化的方法来建立 Action,这些辅助方法叫作 Action Creator。

Stores

图片描述

应用的数据中心,全部应用数据都存放在这里控制,同时包含数据的控制行为,可能包含多个 store

Dispatcher

图片描述

action 的控制者,全部 action 都会经过 dispatcher,由 dispatcher 控制 action 是否应该传入到 store 中,Dispatcher 是一个单例。

View

图片描述

页面的视图,对应 React 的 Component, 视图能够触发 action 到 dispatcher。

须要区别出一种叫控制器 View(Controller View)的类型,这种 View 能够知晓 store 数据,把 store 数据转化为自身的状态,在将数据传递给其余 view 。 而且能够监听 store 数据的改变,当 store 数据改变事后从新设置状态触发重渲染。 能够将控制器 View 对应 MVC 中的控制器,可是差异很大,控制器 View 惟一多作的事情就是监听 store 数据改变,没有其余任何业务处理逻辑。

流程

一样以 TODOMVC 的添加 todo 为例,Flux 中的流程为:

View -> Action(Action Creator -> Action) -> Dispatcher -> Store -> Controller View -> View

  1. View -> Action: 添加按钮事件或者 input 输入的提交事件,View 中将事件转化为 action, action 由 Action Creator 建立。

  2. Action -> Dispatcher: action 统一由 Dispatcher 分配

  3. Dispatcher -> Store: Dispatcher 分配 action 到 Store

  4. Store -> Controller View: 控制器 View 监听 store 的数据改变,将数据转化为自身属性

  5. Controller View -> View: 数据改变自动重渲染全部视图

对比

  1. 渲染策略: 数据改变 Flux 自动渲染,MVC 手动编写更新函数

  2. 事件触发策略: Flux 中全部 action 交给 dispather 分配,MVC 中交给对应的控制器分配

Flux 在核心策略上的不一样是解决 MVC 架构问题的关键

1.6.4 理解 Flux 架构

Flux 架构是很是优雅简洁的,合理利用了一些优秀的架构思惟

分而治之(Divide And Conquer)

数据的处理过程是 Store -> Controller View -> View。 全部数据来自于 Store,页面的渲染层级为 Store 将数据传入 Controller View, 再由 Controller View 传入子 View , 一直到 View 的叶子节点。

这个是一个典型的分而治之策略,将大的页面拆分为小的模块,再由小的模块拆分为小的组件,具体组件负者组件自身的问题,全部子组件都是自私的,不用关心“你们”,只用关心“小家”。

合而治之 - 中心化控制

Flux 把全部的 View 都视做愚民,Store 视做资源的拥有者为统治者,统治者须要提供资源(数据)给平民,可是若是平民企图对资源修改(Mutation),必须得先通知给统治者,让统治者决定是否作处理。

咱们为 Flux 中的概念分配角色

  • View: 平民

  • Action: 资源修改操做

  • Dispatcher: 审核官

  • Store: 统治者

一个企图修改资源的操做能够描述为:

View Require Mutation -> Action -> Dispatcher -> Store -> Mutate Handler

平民提交 Mutation 请求,由审核官控制,审核经过后递交给统治者,统治者再分配给亲信作资源 Mutation

合而治之的策略也等于中心化控制策略, 做为统治者既要懂得放权利(资源的分配),也要懂得控制权利(资源的修改),这种收缩自如的合理性是 Flux 简洁的根本。

同时这种思惟带来的优势以下:

  1. View 的独立性和简单性:View 自身的逻辑简单,不须要知道太多事情,只关心上级传来的数据,这种模式使得 View 是低耦合的,简洁的。

  2. 高可维护性:中心化控制知道全部对资源的操做,若是发生 bug, 能够很快定位问题

函数式编程思想

在 Flux 中数据的单向流动依赖于 View 的肯定性,相同的数据传入相同的组件,获得的结果必然要相同,这是函数式编程的思想。

函数式编程中的纯函数(Pure Function)定义以下:

纯函数是这样一种函数,即相同的输入,永远会获得相同的输出,并且没有任何可观察的反作用

如:

// 纯函数,相同的输入一定有相同的输出
function pure(a, b, c) {
    return a + b + c;
}

// 非纯函数,咱们永远没法肯定 this.a 会变成什么
function notPure(b, c) {
    return this.a + b + c;
}

为了保证组件也能作到 “纯函数” 的特性,相同的属性会获得相同的渲染结果。 在写 React 组件的时候尽可能准守一下约定:

  1. 尽可能使用无状态组件

  2. 除了控制类组件之外其余组件避免使用组件状态

  3. 能够经过属性计算出来的状态不要用状态来表示

  4. 组件的渲染避免外部依赖,按照纯函数的方式写

函数式的优势也是无反作用组件的优势:

  1. 无耦合,可移植性强: 组件可重用性高

  2. 可测试性高:组件无依赖,能够很容易的单独测试组件

1.6.5 Flux 生态

上面已经讲过 Flux 更应该算是 Facebook 提出的一种前端架构模式,而根据这种理念的 Flux 实现有不少,如下是 github star 数较高的一些实现:

  1. Facebook 官方实现

  2. Redux 目前承认度最高的实现

  3. refluxjs

  4. alt

  5. fluxxor

后面咱们会在第四章中专门讲解 Redux 与 React 的应用。

1.6.6 Flux 与 React 实例

@todo

相关文章
相关标签/搜索