一、基本概念
action
dispatcher:接受actions,每个application中只有一个dispatcher.
store:管理application的数据。每个store都在dispatcher中进行注册,并接受actions。store中的数据改变时,会触发change事件。每个application中有多个store. store中只能设置getters,不能有setter,但可以设置内置方法,如_add().
view:视图,通常对应React。当view使用一个store中的数据时,必须对store的change事件进行监听。当发生用户交互时,触发相应的action.

二、 以facebook flux + React为例进行说明。
const React = require('react');
const ReactDOM = require('react-dom');
const Dispatcher = require('flux').Dispatcher;
const dispatcher = new Dispatcher();
const Store = require('flux/utils').Store;
class MyStore extends Store {
constructor(dispatcher) {
super(dispatcher);
this.list = [];
}
__onDispatch (action) {
switch(action.type) {
case 'add':
this.list.push(action.data);
console.log('1', this.list);
// 手动触发事件
this.__emitter.emit('change');
break;
default:
this.data += 'in the default'
}
}
}
var store = new MyStore(dispatcher);
class ContainerUI extends React.Component {
constructor(props) {
super(props);
this.state = {
list: []
}
}
handleClick () {
dispatcher.dispatch({
type: 'add',
data: ReactDOM.findDOMNode(this.refs.input).value
})
}
componentDidMount () {
this.remove = store.addListener(() => {
console.log('2')
this.setState({
list: store.list
})
})
}
componentWillUnmount () {
this.remove();
}
render () {
let list = this.state.list.map(item => <li key={item}>{item}</li>);
return <ul>
<li>
<input type='text' ref='input' defaultValue='' />
<button onClick={ this.handleClick.bind(this) }> add </button>
</li>
{list}
</ul>
}
}
export default ContainerUI;
效果如下:


此外,facebook flux中还提供了reduceStore API
import React from 'react'; const Store = require('flux/utils').ReduceStore; const Dispatcher = require('flux').Dispatcher; const dispatcher = new Dispatcher(); class MyStore extends Store { // ReduceStore中需要重写以下两个方法: getInitialState () { return { year: 2020, month: 2, date: 26 } } // 返回一个State reduce(oldState, action) { switch (action.type) { case 'add': return { year: 2020, month: 2, date: oldState.date + 1 } default: return oldState } } } const store = new MyStore(dispatcher); class ContainerUI extends React.Component { handleClick () { dispatcher.dispatch({ type: 'add' }) } componentDidMount () { this.remove = store.addListener(() => { console.log(store.getState()) }) } componentWillUnmount () { this.remove(); } render () { return <ul> <li> <button onClick={ this.handleClick.bind(this) }> new day comes!</button> </li> </ul> } } export default ContainerUI;
