ReactJS &Flux &Redux 的设计思想与关系

前言:

在WEB1.0时代,数据改变与页面刷新的机制比较简单粗暴:“后端改变state,前端整个页面view刷新”;前端

web2.0时代,咱们但愿:react

“改变state,view自动更新”web

虚拟DOM

浏览器里的DOM tree克隆一份完整的镜像到内存,也就是所谓的“virtual DOM”,编程

当页面的state发生变化之后,根据最新的state从新生成一份virtual DOM(至关于在内存里“刷新”整个页面),将它和以前的virtual DOM作比对(diff),而后在浏览器里只渲染被改变的那部份内容,这样浏览器的性能损耗和用户体验不就都不成问题了吗?redux

**在绝大多数的WEB开发中:**js引擎的性能和内存彻底没有被充分利用,咱们正好能够火力全开,利用js的这部分性能红利,实现内存中virtual DOM的diff工做,完美!后端

ReactJS:

  • react很是具备表达力的jsx语法和完善的模块化结构,设计模式

  • view的组件化和模块化很是有利于分工协做、代码的积累复用以及单元测试,浏览器

伴随着reactJS 前端框架的崛起,redux这些专一于管理state的轻量级框架横空出世;bash

*因为React的“state-view”模式可让开发者的大脑获得一种“单向流”的温馨体验。那为何单向流的思惟状态更加温馨呢?前端框架

这是由于在单向流状态下,要解决的问题如同一个函数映射,已知什么(好比state)是固定不变的,要获得什么(好比view)是定义明确,而人的思惟很是习惯于这种定义明确的、没有“分叉”和“环路”的函数式问题。

页面呈现的state能够经过模块属性(props)从父模块传递到子模块。这种"树状"分流机制,有点像植物将营养(state)从根部不断运输到细枝末叶的过程*

Flux思想:

  • flux 与 react 是彻底独立的概念,咩有直接的关系;
  • flux 不是JS库,而是一种前端代码的组织思想;=>redux 库能够认为是flux 思想的实现;
  • flux 的核心思想和代码实现虽然很简单,可是在model(view)-view 开发模式中,起着很是重要的做用;
  • mvc设计思想: MVC开发模式, 主要讲的是在开发交互应用时,怎样将不一样功能的代码拆分到不一样文件或区块,以便下降代码的耦合度,提升代码的可读性和健壮性。 简单理解就是:要将 Model-View-Controller 这三部分代码拆分到不一样文件。当开发小型的web应用的时候,mvc能够应付;可是当中大型应用的时候,多model,多view的时候,model-view的‘单向流’被破坏带来的混乱,带来难以接受的局面;这种设计模式的model-view关系;facebook团队总结说:MVC模式难以scale up

flux设计模式就是解决以上model-view混乱=>

flux 设计思想的诞生

如今咱们又能够从服务器端的MVC模式中得到灵感了!

由于咱们注意到,服务器端的controller一般也须要对不少Model产生修改,但在代码结构中却集中在一块儿,没有散落一地。缘由很简单:

  • 因为server和client是远程通讯的关系,所以为了尽可能减小通讯耦合,client每一个操做的所有信息都以http请求的形式被归纳成了精简的“做用量”(action)。
  • 请求的url路径约定了用户的操做意图(固然RESTful概念中,请求的method也能够反映操做意图),request参数表征了该“意图”的具体内容。正是基于这个action的抽象,client端的交互操做才能够被集中转移到server端的controller中作统一响应。

对比之下,咱们马上发现上述代码片段中前端MVC模式的“痛点”所在:不是MVC模式错了,而是咱们压根缺乏了一个和用户交互行为有关的action抽象!所以,对model的具体操做才无法从各个view组件中被剥离出来,放到一处。

参考http请求,咱们将要定义的action,须要一个typeName用来表示对model操做的意图(相似于http请求的url路径),还可能须要其余字段,用来描述怎样具体操做model(相似于http请求的参数)。

也就是说,当用户在view上的交互行为(例如点击提交按钮)应当引发Model发生变化时,咱们不直接修改model,而是简单地dispatch一个action(其实跟常见的event机制没有什么区别)以表达修改model的意图,这些action将被集中转移给数据端(models),而后数据端会根据这些action作出须要的自我更新。同时,咱们考虑到react中view组件的树状分流结构,因此有以下图所示:

图中A表示Action,V表示View组件,Models部分的结构会进一步讨论。

稍微总结一下:从代码层面而言,flux无非就是一个常见的event dispatcher,其目的是要将以往MVC中各个View组件内的controller代码片段提取出来放到更加恰当的地方进行集中化管理,并从开发体验上实现了温馨清爽、容易驾驭的“单向流”模式。 因此我以为,Flux与其说是对前端MVC模式的颠覆,倒不如说是对前端MVC思想的补充和优化。

但为了区分于以往的MVC模式,并向facebook的贡献表达敬意,后面咱们将把这种优化后的 Model-View-Controller 开发模式在React背景下正式称为Flux模式

问题:

React的能够经过View Component把页面呈现进行“原子化”拆分(即上图中兰色区域的树状分流结构);

Flux打通了State-View的任督二脉(绿色区域),并经过action抽象把用户交互行为
进行了“原子化”拆分;

复制代码

那么联系上面的图示,咱们天然要问数据端(紫色区域)的处理,能否一样被“原子化”拆分?

redux登场 (数据端的“原子化”)

redux 中的reduce机制,将state端的数据处理进行‘原子化’拆分。redux是来自函数式编程(Functional Programming)的一朵奇葩,听说颇有背景([参考连接](Prior Art | Redux) ) reducer,从代码上说,其实就是一个函数,具备以下形式:

(previousState, action) => newState
复制代码

reducer做为一个函数,能够根据web应用以前的状态(previousState)和交互行为(经过flux中提到的action来表征),决定web应用的下一状态(newState),从而实现state端的数据更新处理。这个函数行为和大名鼎鼎的“Map-Reduce”概念中的Reduce操做很是相似,于是称这个函数为“Reducer”。

"shut up and show me the code" redux.js.org/basics/exam…

这里不打算详细讲解Redux的具体使用,而只想经过一个Redux对state数据进行操做的代码片段,管窥一下reducer机制对数据进行拆分和组装的简洁过程。代码片段以下

其中的todos是和任务列表数据相关的reducer,todo是和单条任务数据有关的reducer。注意:在todos的函数体内调用了todo,并将action做为参数原样传递给了todo,这种干净利落地经过函数调用将action由 “parent reducer” 传递给 “child reducer”,是redux实现数据处理拆分的广泛方式。

回味一下,咱们应该能够体会到,这种数据处理“原子化”拆分的方式和react中view组件的拆分有殊途同归之妙,两者都会造成一种“树状”分流结构(在react的view hierarchy中,数据经过props的直接赋值实现单向流;在redux的reducer hierarchy中,数据经过action的函数传参实现单向流)。

visibilityFilter是和列表显示状态相关的另外一个reducer;combineReducers将visibilityFilter和todos合并为整个应用的reducer,也就是todoApp。这个过程,从感受上也和react中view组件的合并过程很是相像。

createStore是一个工厂函数。经过它,todoApp(至关于一个数据处理的引擎)被装配到整个应用的state容器,也就是store中。能够经过store的getState方法获取整个应用的state;同时,store也是一个event dispatcher,能够经过其dispatch和subscribe方法,分别实现触发action事件和注册对action事件的响应函数。总言之,从概念上来讲 Redux = Reducer + Flux

总结:

全体亮相

如今React开发模式中的几个核心概念已经所有出场亮相。咱们俯瞰一下整个开发流程:首先,react框架为咱们理顺了 store --> view 的“单向”工做流(store是state的容器);而后,redux框架为咱们理顺了 view --> store 的**“单向”**工做流。而且,react和redux都以组件化的形式能够将各自负责的功能进行灵活地组装或拆分,最大程度上确保咱们“一次只须要专一于一个局部问题”。具体来讲,分为如下步骤:

1.单例store的数据在react中能够经过view组件的属性(props)不断由父模块**“单向”**传递给子模块,造成一个树状分流结构。若是咱们把redux比做整个应用的“心肺” (redux的flux功能像心脏,reducer功能像肺部毛细血管),那么这个过程能够比做心脏(store)将氧分子(数据)经过动脉毛细血管(props)送到各个器官组织(view组件)

2.末端的view组件,又能够经过flux机制,将携带交互意图信息的action反馈给store。这个过程有点像将携带代谢产物的“红细胞”(action)经过静脉毛细血管又泵回心脏(store)

3.action流回到store之后,action以参数的形式又被分流到各个具体的reducer组件中,这些reducer一样构成一个树状的hierarchy。这个过程像静脉血中的红细胞(action)被运输到肺部毛细血管(reducer组件)

4.接收到action后,各个child reducer以返回值的形式,将最新的state返回给parent reducer,最终确保整个单例store的全部数据是最新的。这个过程能够比做肺部毛细血管的血液充氧后,又被从新泵回了心脏

5.回到步骤1

用图示的方式表达:

  • 图中A表示Action,V表示View组件,R表示Reducer。

  • 为了确保咱们比较容易理解程序的全局行为,或者说提升程序行为的肯定性(predictable),咱们通常指望具备相似职能的代码片段被“平铺”着摆放在一。

  • 所以图示中相同颜色区域的代码一般会被放到同一个文件夹/文件中。

  • 另外,一样出于提升程序的肯定性,redux所遵循的函数式编程鼓励咱们使用pure function和immutable。

参考: www.cnblogs.com/dreamingbao…

相关文章
相关标签/搜索