1.6 flux介绍
这一节将介绍 React 的核心应用架构模式 Flux,包括内容:
Flux 介绍
MVC 架构之痛
Flux 的理解
Flux 相关库和工具介绍
Flux 与 React 实例
Flux 介绍
MVC 架构之痛
Flux 的理解
Flux 相关库和工具介绍
Flux 与 React 实例
最后我们将会把之前的 TODOMVC 改为 Flux 的架构。
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
View -> Action: 添加按钮事件或者 input 输入的提交事件
Action -> Controller: 控制器响应 View 事件
Controller -> Model: 控制器依赖 Model, 调用 Model 添加 todo
Model -> View: View 监听 Model 的改变添加 todo 事件,在 HTML 中添加一个新的 Todo 视图
问题
对于新增一个 todo ,需要编写一个视图渲染处理函数,函数内添加新项目到列表中。同理对于删除一个 todo,也会有一个处理函数。当业务逻辑变多过后,可能有很多模型需要做增删改的功能,与之对应的就是我们需要精心构建这么多的渲染处理函数。 这种局部更新模式是高性能的关键所在,但问题是:
更新逻辑复杂,需要编写大量的局部渲染函数
问题定位困难,页面的当前状态是有数据和这些局部更新函数确定的
如何解决
如果渲染函数只有一个,统一放在 App 控制器中,每次更新重渲染页面,这样的话:
任何数据的更新都只用调用重渲染就行
数据和当前页面的状态是唯一确定的
重渲染也有弊端,会带来严重的性能问题,重渲染和局部渲染各有好坏,对 MVC 来说这是一个两难的选择,无法做到鱼和熊掌兼得。
那如何才能兼顾两种模式的优点?
1.6.3 Flux 架构
通过 React + Flux
就可以完美解决 MVC 的问题。
重渲染: 在 React 中每次渲染都是重渲染,且不影响页面性能,是因为重渲染的是 Virtual Dom。这就意味着完全不用去关系重渲染问题,增删改的渲染都和初始化渲染相同入口
数据和状态一致性: 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
View -> Action: 添加按钮事件或者 input 输入的提交事件,View 中将事件转化为 action, action 由 Action Creator 创建。
Action -> Dispatcher: action 统一由 Dispatcher 分配
Dispatcher -> Store: Dispatcher 分配 action 到 Store
Store -> Controller View: 控制器 View 监听 store 的数据改变,将数据转化为自身属性
Controller View -> View: 数据改变自动重渲染所有视图
对比
渲染策略: 数据改变 Flux 自动渲染,MVC 手动编写更新函数
事件触发策略: 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 简洁的根本。
同时这种思维带来的优点如下:
View 的独立性和简单性:View 自身的逻辑简单,不需要知道太多事情,只关心上级传来的数据,这种模式使得 View 是低耦合的,简洁的。
高可维护性:中心化控制知道所有对资源的操作,如果发生 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.6.5 Flux 生态
上面已经讲过 Flux 更应该算是 Facebook 提出的一种前端架构模式,而根据这种理念的 Flux 实现有很多,以下是 github star 数较高的一些实现:
Redux 目前认可度最高的实现
后面我们会在第四章中专门讲解 Redux 与 React 的应用。
1.6.6 Flux 与 React 实例
1.6 flux介绍的更多相关文章
- 【11】react 之 flux
Flux 是 Facebook 使用的一套前端应用的架构模式.React 标榜自己是 MVC 里面 V 的部分,那么 Flux 就相当于添加 M 和 C 的部分. 1.1. Flux介绍 Flux并 ...
- Flux和ExtJS MVC框架的异同点介绍
Flux是Facebook在现有MVC框架数据流动复杂,难以设计和维护大型的前端应用的情况下设计的一种新的数据架构协议.叫做协议是因为Flux本身就像MVC一样,规定了一种机制,但是Facebook提 ...
- flux架构的详细介绍和使用!
结构分为四个 视图 view动作 action派发器 dispatcher数据商店 store 流程: 用户操作视图 视图(view)发送动作(action)到派发器(dispatcher) 由派发器 ...
- redux+flux(一:入门篇)
React是facebook推出的js框架,React 本身只涉及UI层,如果搭建大型应用,必须搭配一个前端框架.也就是说,你至少要学两样东西,才能基本满足需要:React + 前端框架. Faceb ...
- 【原】flux学习笔记
最近React(web/native)依旧如火如荼,相信大家都跃跃欲试,入职新公司,现在的团队也开始在React领域有所尝试. 2016年应该是React 逐渐走向成熟的一年.之前在原来公司搞不懂的问 ...
- Flux Demo解析
最近学习了阮一峰老师的博文 "Flux入门教程",博文中详细介绍了Flux框架和Controller view模式,并提供了Demo,受益匪浅. 现特参考阮老师的Demo,绘制了一 ...
- 使用 React 和 Flux 创建一个记事本应用
React,来自 Facebook,是一个用来创建用户界面的非常优秀的类库.唯一的问题是 React 不会关注于你的应用如何处理数据.大多数人把 React 当做 MV* 中的 V.所以,Facebo ...
- Flux demo
Flux demo Introduction flux应用架构如下图所示,本文并不是讲述怎么立即做一个酷炫的应用,而是讲述如何依照这种框架,来进行代码的组织.我们先把这个流程转述为文字:抛开与webA ...
- Flux是一个Facebook团队的前端开发架构
Flux是一个Facebook团队的前端开发架构 Flux introduction 本文组成: React 官方文档翻译 相关实践心得. 内容上是Flux的介绍,例子将会在以后写出.一旦稍微多了解一 ...
随机推荐
- ibatis 中的 $和#的区别
在sql配置中比如in(#rewr#) 与in ($rewr$) 在Ibatis中我们使用SqlMap进行Sql查询时需要引用参数,在参数引用中遇到的符号#和$之间的区分为,#可以进行与编译,进行类型 ...
- mysql 自动加上编号
SELECT (@i:=@i+1) i,user_id,user_name FROM dt_user_all_orders, (SELECT @i:=0) as i
- IDEA 报错记录
IDEA 报错记录 Process finished with exit code 0 这种主要是配了默认的 Tomcat ,然后又配置了外部的 Tomcat.解决办法,注释掉默认的: <dep ...
- upc组队赛6 Bumped!【最短路】
Bumped! 题目描述 Peter returned from the recently held ACM ICPC World finals only to find that his retur ...
- python学习笔记:操作数据库
1.下载安装模块 第一种:cmd下:执行命令下载安装:pip3 install pymysql 第二种:IDE下pycharm python环境路径下添加模块 2.连接数据库 import pymys ...
- 把数字翻译成字符串 --剑指offer 46题
# 给一个字符串,按如下规则把它翻译成字符串:1翻译成a,2翻译成b,...25翻译成z:一个数可以有多种翻译方式,比如122可以翻译成abb和kb还可以翻译成aw即3种翻译方式.计算一个数字有几种翻 ...
- Java不可变对象
在创建状态后无法更改其状态的对象称为不可变对象.一个对象不可变的类称为不可变类.不变的对象可以由程序的不同区域共享而不用担心其状态改变. 不可变对象本质上是线程安全的. 示例 以下代码创建了不可变类的 ...
- shell编程:函数的返回值
函数的返回值两种形式 return 0-255 0表示成功,1-255表示失败-------通常用于判断 echo 返回一个字符串------------通常用于返回一个执行的结果 return.sh ...
- java部署:CentOS 7下Tomcat安装与配置教程(Tomcat开机启动)
一.前言 1.本教程主要内容 Tomcat安装与基础配置 Tomcat开机启动配置 2.本教程适用范围与环境信息 适用范围 软件/工具 版本说明 CentOS CentOS 7 Tomcat Tomc ...
- Linux下svn更新含有中文名称的库无法更新问题
Linux下更新含有中文名称的库文件时,出现如下提示: SVN Error: Can't convert string from native encoding to 'UTF-8' 通过google ...