一、基本概念:
Flux是Facebook用来构建客户端Web应用的架构,通过单向数据流的方式来实现React的视图组件与Model之间的数据流动。与其说它是正式的框架,倒不如说它是一种模式。
Flux应用主要由三大部分组成:dispatcher,model,view(React视图组件)。在这里,并没有MVC架构中的controller这一层。但是它有controller-views。controller-views-view处于分层结构的顶部,负责订阅store中的数据并依次传递给它的children。dispatcher负责分发事件,model负责保存数据,响应事件以及更新数据,
二、结构与数据流:
用户输入 → action creator 将action提供给dispatcher → dispatcher触发在store中注册的回调函数,将action派发给所有store → 在回调函数内,store对每一个action做出响应并更新状态 → store随后触发了一个change事件去提醒controller-views数据层发生了更新 → controller-views监听这些事件并在事件处理器中订阅这些数据 → controller-views调用自身的setState()触发自身以及子视图的重新渲染
在此过程中,数据流向都是单向的。应用状态只保存在store中,使得应用其他部分高度解耦。在store之间存在依赖关系时,它们保持了严格的分层,由dispatcher来管理同步更新。
而双向数据流会导致级联更新。发生在一个对象内的变化会导致另一个对象也变化,这会导致更多的变化。随着应用变得复杂,级联更新将会导致用户与界面的交互结果变得不可预知。而如果数据流向都是单向的话,系统整体便可预测。
三、Flux架构的各个部分
3.1 Dispatcher
在Flux应用中,dispatcher 是一个用以管理所有的数据流的中央处理器。本质上讲,它是一个回调函数登记库。当action creator提供了新的action给store时,所有的store都会通过登记在库的回调函数来接收action。随着应用变得复杂,dispatcher 的作用也越发重要。它可以通过掌控已注册的回调函数的触发顺序来管理store间的依赖:store可以声明式地等待其他store更新完毕以后再做响应更新。
3.2 Stores
store 包含了应用的状态以及逻辑,它的作用有一点类似于MVC模式的model,但它们管理了多个对象的状态,并不代表像ORM模型那样的单一记录。store既展示了集合model的特性,又展示了特定逻辑域的单一model。
store调用dispatcher的register方法进行注册,并提供一个以action作为参数的回调函数。在回调函数内部有一个switch语句,通过判断action的类型来决定进入哪个钩子函数,并进行相应的更新。store更新之后,便广播一个change事件声明state已变,views便可获得新的state并更新视图。
另外,在stores外面并不能看到store是如何管理数据的,stores对外只暴露getter()方法而不暴露setter()方法。要改变stores只能通过 action creator/dispatcher。
3.3 Views -- Controller-Views
controller-views 处于view分层结构的顶端,将store与view进行 “胶合” :它监听从store广播出来的事件,用store的getter方法获取新的state,然后调用自身的setState()方法让render得以触发。
通常,我们会通过一个对象把整个store的状态传递到视图层,让视图层取得各自所需的状态。这样做将类控制器的行为保留在了分层结构的顶端,尽可能地保持了子视图的纯净,也减少了需要管理的属性。
有时,为了使组件简单,且易于封装,我们需要一个更深入的Controller-Views。但是,它会让引入一个新的、潜在的冲突入口点来破坏单一的更新数据流。因此,在开发时需要权衡一下组件简单化的增益与多个数据更新流的复杂性。后者可能会导致React的重复渲染,调试起来也会比较困难。
3.4 Actions
dispatcher 暴露给我们一个方法,以此可以向store派发一个动作,这个动作称之为action。action的创建被封装在了一个能够被视图的事件处理器所触发的方法内,所以这个方法可以是对用户交互进行的响应(也可以由服务器触发,例如数据的初始化或者服务器数据更新时需要向应用提供数据)。action creator 包含了type与payload等字段,用以描述一个事件以及与更新相关的数据。