Flux
在2013年,Facebook让React
亮相的同时推出了Flux框架,React
的初衷实际上是用来替代jQuery
的,Flux
实际上就可以用来替代Backbone.js
,Ember.js
等一系列MVC
架构的前端JS框架。
其实Flux
在React
里的应用就类似于Vue
中的Vuex
的作用,但是在Vue
中,Vue
是完整的mvvm
框架,而Vuex
只是一个全局的插件。
契机:React
只是一个MVC中的V(视图层),只管页面中的渲染,一旦有数据管理的时候,React
本身的能力就不足以支撑复杂组件结构的项目,在传统的MVC
中,就需要用到Model和Controller。Facebook对于当时世面上的MVC
框架并不满意,于是就有了Flux
, 但Flux
并不是一个MVC
框架,他是一种新的思想( 新的架构思想 )。
Flux 组成部分
- View: 视图层 ( 用React的组件来代替 )
- ActionCreators(动作创造者):视图层发出的消息(比如mouseClick)
- Dispatcher(派发器):用来接收Actions、执行回调函数
- Store(数据层):用来存放应用的状态,一旦发生变动,就提醒Views要更新页面
Flux的流程:
- 组件获取到store中保存的数据挂载在自己的状态上
- 用户产生了操作,调用actions的方法
- actions接收到了用户的操作,进行一系列的逻辑代码、异步操作
- 然后actions会创建出对应的action,action带有标识性的属性
- actions调用dispatcher的dispatch方法将action传递给dispatcher
- dispatcher接收到action并根据标识信息判断之后,调用store的更改数据的方法
- store的方法被调用后,更改状态,并触发自己的某一个事件
- store更改状态后事件被触发,该事件的处理程序会通知view去获取最新的数据
Flux的使用流程
使用flux写一个计数的例子 count
- 要想使用FLux架构思维,需要通过一个工具进行使用, 这个工具就是flux
- 安装 flux
$ yarn add flux
- 在src目录下 新建store目录,里面新建index.js
- store有两个功能
- 存储数据
- 当数据发生改变时,视图要进行更新 ( 当前组件中的state发生了改变,从新从store中获取数据,要想重新复制,那么要通过事件的发布,订阅 )
- store有两个功能
const EventEmitter = require( 'events' ).EventEmitter //通过node引入events模块
//react之所以可以用node,模块,底层用的webpack,webpack底层又是node
const store = {
...EventEmitter.prototype, //通过prototype获取on。emit 进行事件发布和订阅
state: { //我们可以将state单独提取出来,然后import引入
count: 0
},
getState () {
return this.state
}
}
export default store
- 将store中的数据显示在组件(视图)中
import store from './store' //引入store
class xxx extends React.Component{
constructor () {
super()
this.state = {
count: store.getState().count //给count赋初始值store.getState()下的count
}
}
render () {
return (
<div>
<p> { this.state.count } </p> //可以输出啦
</div>
)
}
}
-
用户操作,用户点击按钮,执行当前组件中的方法,这个方法的逻辑实际上是actionCreators中的方法
-
创建actionCreators.js
- actions的发送要通过dispatcher来发送
import * as type from './type' //引入类型文件 import dispatcher from './dispatcher'; const actionCreators = { increment () { // 创建动作 let actions = { type: type.INCRMENT // 将类型单独创建出来 } // dispatcher来通过dispatch 发送actions dispatcher.dispatch( actions ) } } export default actionCreators
-
创建dispatcher.js
import { Dispatcher } from 'flux'; import * as type from './type' import state from './state' const dispatcher = new Dispatcher() // dispatcher.register( callback ) dispatcher.register( ( actions) => { switch ( actions.type ) { case type.INCRMENT: //判断actions.type 进行操作 // 用户操作了 state.count++ break; default: break; } }) export default dispatcher
-
通过store的事件的发布和订阅进行 当前组件中 state 的重新赋值
- 当我们点击按钮是,要通过store的事件的订阅给当前组件的state重新赋值,要想这样做,我们必须进行事件的发布
- 组件的生命周期中,数据可以进行一次修改的可以往
componentWillMount // componentDidMount
- 这个事件的发布往哪里写
- 写在
componentDidMount
中
- 写在
- 这个事件的订阅那里写
- 我们点击按钮的时候,就要修改当前组件的state,也就是要进行事件的订阅,写在点击事件中
- 这个事件的发布往哪里写
import React from 'react';
import './App.css';
import store from './store'
import actionCreators from './store/actionCreators';
class App extends React.Component {
constructor () {
super()
this.state = {
count: store.getState().count
}
}
increment () {
actionCreators.increment()
store.emit('count') //订阅
}
componentDidMount () {
store.on('count', () => { //发布
this.setState({
count: store.getState().count
})
})
}
render () {
return (
<div>
<h3> flux </h3>
<button onClick = { this.increment }> + </button>
<p> count: { this.state.count } </p>
</div>
)
}
}
export default App;