说一说 Flux的小白知识

MV*

说Flux之前,先说说熟知的MV*模式。 MV*一般指MVC/MVVM.
MVC如我们熟知:

  • M = Model,负责数据的保存,检验,获取等。
  • V = View,数据的展示,DOM元素。
  • C = Controller,与传统的controller定义不同,前端中的controller的定义比较模糊。但一般作为Model和View之间的协调。

而MVVM,就是在MVC的基础上,用VM(ViewModel)替代Controller。
也就是数据绑定,界面与VM的数据状态可以相互影响。

说到这里,其实不难想象,数据可以多方影响,来源不明且多样。混乱的数据流向导致项目后期,开发维护的难度加大。Model的构建数量过多,会影响View的构建结构与渲染优化。

Flux

Flux 的命名来自于拉丁语Flow。是一套基于dispatcher的前端应用架构模式。
\>核心思想是数据和逻辑永远单向流动。
对比MV* 结构,Flux模式有着数据来源单一,数据变动可溯源的优点。让逻辑架构更加谨慎清晰。

这里和React组件间的单向流动不同。React的单向数据流动是一般指基于Props的组件间通信设计。而Flux的单向数据流,则是基于整个架构上的。

1. Dispatcher

一个全局唯一的数据流处理中心。有3个主要API:

  • dispatch(object payload) : void

用于分发action。执行已注册的监听。

* **register(function callback) : string**
注册监听用于响应dispatch。 返回一个token可供waitFor()使用。
* **waitFor(array ids) : void**
当在回调中遇到waitFor()时,该回调暂停执行。在waitFor()完成执行并回调之后,再继续执行原始回调。此方法可以用于等待并执行其他store操作。

*action是一个对象类型,在FSA规范中对其字段进行了列举:type,error,payload,meta。其中type(或者name)为必须,是store根据action修改数据的依据。
在Facebook的Flux实例源码中,在Dispatcher类里定义了一个\_callbacks数组,保存了在register方法中注册的监听器。并在dispatch方法中遍历执行,且把action作为参数传入监听函数。

2. Store

一般有以下几个功能:

  • 保存状态数据(state)。
  • 暴露一个Getter用于获取状态
  • 定义修改数据的逻辑。
  • 调用Dispatcher.register方法将自己注册为一个监听器。
  • 定义一个更新监听方法

当调用dispatch分发action,store在register方法中注册的监听就会被调用,同时得到传入action。
store将根据action携带的type判断是否响应操作。如响应,调用内部的数据修改逻辑。并在执行完毕后触发更新事件。

3. Controller-View/View

Controller-View一般作为最顶层的View,负责Store和View之间的数据传递。

  • **进行store与View的绑定,定义数据更新及传递方式。**这里说的View一般是React,当然也可以是其他框架。
  • **监听Store发出的更新事件。**当Store更新后,Controller-View会重新获取store中的数据,并触发界面重绘。

class CounterContainer extends Component {
static getStores() {
return [CounterStore];
}

static calculateState(prevState) {
return {
counter: CounterStore.getState(),
};
}

render() {
return ;

}
}

const container = Container.create(CounterContainer);
上面是Flux官方文档中将一个React Class创建为Controller-View的简单调用实例。class向外暴露getStores、calculateState两个方法:

  • getStores用于绑定Class关联的Store。
  • calculateState用于获取Store中的数据转化为自身的State,并作为props传给子组件。

Container.create方法中,会获取绑定的Store中dispatchToken,然后根据dispatchToken利用waitFor方法等待Store完成数据更新逻辑,然后执行更新回调。
当Store触发更新后,Container会调用setState方法更新State,同时触发画面渲染更新。
当然关联store、更新回调等可以有多种实现方法,以上只是其中一种思路。

View就是界面表现了,View可以通过props获得Container传入的数据。
如果View需要修改数据,必须使用dispatcher分发action的方式进行修改。
这也是单向数据流的重要特征,view不能直接修改数据。

说起Flux,很多第一句就是单向数据流。但其实数据中心化控制,也是特点之一。
所有的更改,必须通过action发出,dispatcher分配。store中心化控制了数据,令数据管理和问题追查变得清晰容易。
action的管理,令架构不用关心辨别数据更新的触发方式,所有触发方式都抽象成了action。Flux架构并非React独有,也能作为其他组件框架的状态管理方案。
前面说到Flux对于MV*架构的优点,当然Flux本身也有的坑。虽然后面提出的Redux,则对Flux中state与更新逻辑没有分离抽象,没有对URL路由进行管理等问题进行改进。但Flux只是一种设计约定,各人对其都有自己的观点和想法。与其他架构相比其实没有绝对的优势劣势,只是提供解决方案的一种。

你可能感兴趣的