阿里云云服务器双12活动又来了,低至1
折 ,真心觉得很划算了,可以点击本条内容直接参与
Flux的出现是复杂app重构的必然结果. 如果你仅仅只是想写几个小demo, 或者小产品, 那么使用Flux 完全是得不偿失的. 因为他的复杂度, 可能比你的业务逻辑还多. so, what’s Flux on earth? 很简单, flux 是利用订阅发布模式的一种语法糖. 他包含4个部分: Action,Dispatch,Store,View. 可以看下图的基本架构.
虽然, 上面是一个闭环, 但是,起点应该从哪里开始呢? 很简单, 从用户开始==> View. 通过View 触发不同的Action, 然后通过中介者模式, 触发对应的Store, 来对数据执行不同的操作, 并且,如果需要更新视图的话, 就需要在Store里面调用this.setState方法.
Ps: 如果你的项目不大的话, 就不要用flux了. 因为这样,真的没用.
ok, 我们来实践一下, 使用React+Flux 来模仿人的行为. run ,speak, walk. 首先定义Action:
const Dispatcher = require('flux').Dispatcher;
let manager = new Dispatcher();
// 定义行为
const Actions = {
run(){
manager.dispatch({
type:'RUN',
time:4
})
},
speak(){
manager.dispatch({
type:'SPEAK',
time:10
})
},
walk(){
manager.dispatch({
type:'WALK',
time:20
})
}
}
这里补充Dispatcher两个api:
- dispatch: 用来触发事件. 向register的管理中心传递信息
- register: 用来处理所有通过dispatch触发的内容
这里, 我们定义一下Store. 用来进行计时. 这里, 额外用到了fbemitter这个类库, 用来实现事件型的订阅发布模式. 实际上,他的工作和Dispatcher是一样, 通过事件触发来传递信息. 不过,fbemitter可以正对不同类型的事件进行触发, 事实上, 我们如果要求不高, 完全可以使用fbemitter进行代替Dispatcher.
const EventEmitter = require('fbemitter').EventEmitter;
let emitter = new EventEmitter();
// 定义Store
const Store ={
time:0
}
Store.dispatchToke = manager.register((action)=>{
Store.time+=action.time;
emitter.emit('change',Store.time,action.type);
})
最后,来看一下关键的组件部分
class Person extends Component{
constructor(){
super();
this.state={
time:Store.time
}
}
componentDidMount(){
this.subscription = emitter.addListener('change',(time,type)=>{
alert(` now I am ${type}ING
I spend ${time} minutes`);
this.setState({
time:time
})
})
}
render(){
return (
<div>
<button onClick={this.run.bind(this)}>run</button>{' '}
<button onClick={this.speak.bind(this)}>speak</button>{' '}
<button onClick={this.walk.bind(this)}>walk</button>{' '}
</div>
)
}
run(){
Actions.run();
}
speak(){
Actions.speak();
}
walk(){
Actions.walk();
}
}
最后我们来梳理一下Flux的整体架构吧.
那应该怎么写Flux呢? 因为Flux已经把数据流的流向给定死了, 所以, 这也只给了我们一条思维路径. 由Action=>Store=>View=>Event
-
首先,了解你需要通过View的事件,执行那些动作. 所有的事件都是为了完成一些列动作而设置, 所以, 这也可以很容易抽象出Actions. 并且设置相应的dispatch传入适当的参数.
-
抽离所有的数据处理, 全部放到Store里. 在Store里,进行Dispatcher 的 register. 实现Actions和Store的连接. 设置Store 需要进行页面更新的自定义事件.
-
在UI组件中, 通过this.state 获取Store 暴露的原始数据. 在componentDidMount或者constructor 中,绑定Store设置的自定义事件. 并且UI中,设置事件和Actions的连接. 这里,就实现了 Store=>View=>Action 的single-direction.