Flux的核心思想
- 数据和逻辑永远是单向流动的,即:unidirectional data flow

Flux的组成
- 3大部分:
- dispatcher(分发事件)
- store(保存数据,同时响应事件并更新数据)
- view(订阅store中的数据,并使用这些数据渲染相应页面)
- 其他部分:
- controller-view(将view和store进行绑定)
- action creators(创建action)

Dispatcher可以看成是 central hub;用户与界面交互会生成一个action,这个action通过Action Creator创建(每个action creator中封装了分发action的操作,即dispatch);store负责数据的保存和修改,并注册一个callback用于监听Dispatcher分发的action,根据action来修改数据;当数据被修改后,store会发送一个change event,controller-views监听到这个event后会重新获取store中的数据,并调用自己的setState(),触发所有子组件的更新
使用Flux创建应用
目录结构
|
|
dispatcher
- 作用:用来分发事件
- 在React中使用flux的
Dispatcher- 主要的方法有:
register(callback)(注册一个监听器)、dispatch(action)(分发一个action)123import {Dispatcher} from 'flux'const commentDispatcher = new Dispatcher()export default commentDispatcher
- 主要的方法有:
action creator
作用:用来创建action
- action:一个javascript对象,用于描述一个事件以及需要改变的相关数据123{type: 'OPEN_LOGIN_DIALOG'}
- action:一个javascript对象,用于描述一个事件以及需要改变的相关数据
action creator定义了一系列的操作函数- 函数内部逻辑:使用
dispatcher.dispatch分发一个action12345678loadComment () {commentDispatcher.dispatch({type: types.LOAD_COMMENT,payload: {loading: true}})}
- 函数内部逻辑:使用
store
- 作用:负责存储数据、修改数据
store的逻辑:- 定义存储数据的变量
- 定义监听器:
store会调用dispatcher.register方法注册一个监听器。当dispatcher的dispatch方法分发一个action时,store注册的监听器就会被调用,同时得到这个action作为参数。这个监听器的callback根据action.type来执行相应的修改数据的逻辑,在数据修改后触发一个更新事件 - 暴露获取数据、监听数据改变的方法123456789101112131415161718192021222324252627// 定义存储数据的变量let data = {loading: false, comment: []}// 暴露一个对象,这个对象有获取数据、监听数据改变的方法const commentStore = {getComment () {return data},emitChange () {emitter.emit('change')},addChangeListener (callback) {emitter.on('change', callback)},removeChangeListenr (callback) {emitter.removeListener('change', callback)}}// 定义监听器commentDispatcher.register(function (action) {switch (action.type) {case types.LOAD_COMMENT_SUCCESS:data = Object.assign({}, data, action.payload)// 发送一个更新事件commentStore.emitChange()}})export default commentStore
controller-view
- 作用:是整个应用最顶层的view,监听
store发送的change event,并重新获取数据传递给子组件 controller-view的逻辑:- 初始化:调用
store暴露的getter获取数据并设置为自己的state,在render时以props的形式传给自己的子组件 - 注册监听器:监听数据更新的事件,
store更新后,controller-view会重新获取store中的数据,然后调用setState触发界面重绘 - 组件卸载时,移除监听器123456789101112131415161718192021222324252627class App extends Component {constructor () {super()this.state = {...store.getComment()}}onChnage = () => {this.setState({...store.getComment()})}componentDidMount () {actions.loadComment()store.addChangeListener(this.onChnage)}componentWillUnmount () {store.removeChangeListenr(this.onChnage)}render () {return (<div className='App'><CommentList data={this.state.comment} /></div>)}}
- 初始化:调用
view
- view层不能直接修改
store中存储的数据,只能通过dispatcher分发事件,间接触发store更新数据123456// 当提交评论时,调用actionCreator的addComment方法onHandleClick = () => {...action.addComment(newData)...}
- 完整代码:https://github.com/xiaoxiaojing/ToDoDo/tree/master/react/demo-comment-with-flux
- 参考文档
- 《深入React技术栈》
- In Depth Overview