React不适合来管理应用数据,而Redux就是管理应用状态的框架。Flux是单向数据流框架的始祖,而Redux是Flux理念的更强实现。所以理解Flux有助于对Redux更好的理解与使用。
MVC框架中,view层与model层直接交互会让他们之间的依赖关系变得复杂。Flux的严格数据流控制能让视图与数据之间的依赖关系清晰可见,降低耦合,增加可读性与可维护性。
下面是Flux的流程图。
从流程图中我们很容易看出,现在更改数据的唯一方式就是Actions。这样对数据流的方向进行了严格控制。
四个概念
- Action: 驱动dispatcher
- Dispatcher: 分发器,维护Store的状态
- View:视图,显示用户界面
- Store: 存储数据,处理数据逻辑
javascript具体的实现思路如下:
1、 引入Flux框架,实例化一个分发器(AppDispatcher)。
import { Dispatcher } from 'flux'
const AppDispatcher = new Dispatcher()
2、 定义action的行为。
const doSomething = (params) => {
AppDispatcher.dispatch()
}
// dispatch函数接受对象类型的参数,一般包含type属性,用来标识该行为,如
const increment = () => {
AppDispatcher.dispatch({
type: 'increment'
})
}
3、 定义Store
Store决定着view层的数据来源,Flux的Store与Redux的Store是这两个框架最重要的区别。在Flux中,一般会存在多个Store(如果需要数据处理,一般一个组件创建一个Store)。当Action触发时,这个动作会派发给所有Store,引起Store对象的状态改变。
定义Store的时候需要注意的是:一般会把Store定义成EventEmitter的实例,因为需要Store监听并分发事件。通俗地说就是,当Action触发了Store状态改变时,Store会向外通知该变化(emit),然后监听器(on)就能通知到某个执行程序(函数),函数会执行实现响应。
const doSomethingStore = Object.assign({}, EventEmitter, {
// getStoreValue方法向外暴露当前Store的状态,也是外部获取该Store状态的唯一方法
getStoreValue: function () {
return doSomethingStore.values
},
// 监听器,Store内部状态变化时,callback执行
addEventListener (callback) {
this.on(event, callback)
},
// 内部Store变化,向外通知变化
emitEvent () {
this.emit(event)
},
// 移除监听器
removeEventListener(callback) {
this.removeListener(event, callback)
}
})
4、注册行为
注册action就是调用 register 方法,返回值作为该Store的唯一标识,可用于其他Store对该Store的引用。
doSomethingStore.dispatchToken = AppDispatcher.register((action) => {
// if...else... || switch
// 通过action的type确定当前行为,并将状态的改变emit出去。
// doSomethingStore.emitEvent()
})
//因为action会触发所有Store,用waitFor可以决定Store状态改变的先后顺序:
AppDispatcher.waitFor([doSomethingStore.dispatchToken])
doOtherthingStore.emitEvent() // 先改变doSomethingStore状态,再改变doOtherthingStore的状态
总结
Flux严格地控制了数据的传递方向,让view层与model层之间的逻辑清晰易懂。但是Flux也存在Store之间的显性依赖(waitFor),不能用于后端等缺点。