flux: flux思路的代码实现模板

更新于 2018-11-21  约 9 分钟
  • Store
\\ExampleStore.js

//引入dispatch层暴露出来的方法
import AppDispatcher from '../dispatcher/AppDispatcher';
import EventEmitter from 'events';
import ActionTypes from '../constants/ActionTypes';


const CHANGE_EVENT = 'change';

const defaults = {
  a: [],
  b: null,
  c: 1,
};

//定义store中需要被使用的数据流a, b, c的默认值
let _a = defaults.a;
let _b = defaults.d;
let _c = defaults.c;

class ExampleStore extends EventEmitter {
  //定义view层可以获取store层数据a的方法
  getA() {
    return _a;
  }

  //定义view层可以获取store层数据b的方法
  getB() {
    return _b;
  }

  //定义view层可以获取store层数据c的方法
  getC() {
    return _b;
  }

  //告知view层store有数据更新
  emitChange() {
    this.emit(CHANGE_EVENT);
  }

  //在view层生命周期为componentDidMount时调用的监听函数,一旦store层有更新便立刻调用callback(回调函数),
  //回调函数由view层定义,通过调用getA(),getB(),getC()函数获取得到更新的a,b,c值,并通过this.setState()
  //更新view层state数据的状态,使得数据更新到页面上
  addChangeListener(callback) {
    this.on(CHANGE_EVENT, callback);
  }

  //在view层申明周期为componentWillUnmount时调用的函数,组件卸载前将回调函数去除
  removeChangeListener(callback) {
    this.removeListener(CHANGE_EVENT, callback);
  }
}

let exampleStore = new ExampleStore();

AppDispatcher.register(function(action) {
  switch (action.actionType) {

    //定义更新数据流a的方法
    case ActionTypes.EXAMPLE_UPDATE:
      _a= action.a;
      exampleStore.emitChange();
      break;

    //定义重置数据流a的方法
    case ActionTypes.EXAMPLE_CLEAR:
      _a = default.a;
      exampleStore.emitChange();
      break;
    
    //根据具体需求定义更多的方法,接收action层的dispatch并接收action传来的数据  
    ......

    default:
      break;
  }
});

//将实例化后的ExampleStore对象暴露给view层使用
export default exampleStore;
  • Action
\\ExampleAction.js

//引入dispatch层暴露出来的方法
import AppDispatcher from '../dispatcher/AppDispatcher';
import ActionTypes from '../constants/ActionTypes';

//封装的fetch方法,用于向后端通信,调用接口,获得数据
import {cfetch, checkStatus, parseJSON} from '../utils/cfetch';

class ExampleActions {
  //通过fetch向服务器发送异步请求,在检查完后端返回的状态码,解析完json后dispatch store层
  updateA(id) {
    cfetch('/update/' + id)
    .then(checkStatus)
    .then(parseJSON)
    .then(function(json) {
      AppDispatcher.dispatch({
        actionType: ActionTypes.EXAMPLE_UPDATE,
        a: json
      });

    });
  }

  //入上操作,不需要异步的行为
  clear() {
    AppDispatcher.dispatch({
      actionType: ActionTypes.EXAMPLE_CLEAR
    });
  }
}

//将实例化后的ExampleActions对象暴露给view层使用
export default new ExampleActions;
  • View
//ExamplePage.js

import React, {Component, PropTypes} from 'react';
//引入action层暴露出来的方法
import ExampleActions from '../../actions/ExampleActions';
//引入store层暴露出来的方法
import ExampleStore from '../../stores/ExampleStore';

//定义获取store层的最新值的函数,监听到store触发时会用到
function getExampleState() {
  return {
    a: ExampleStore.getA(),
    b: ExampleStore.getB(),
    c: ExampleStore.getC(),
  }
}

class ExamplePage extends Component {
  constructor(props) {
    super(props);
    
    //组件初始化时,获取store层的默认值
    this.state = {
      a: ExampleStore.getA(),
      b: ExampleStore.getB(),
      c: ExampleStore.getC()
    };
  }
  
  componentDidMount() {
    //添加监听函数
    ExampleStore.addChangeListener(this._onExampleChange);

    //此时可以调用action函数向后端发送异步请求,更新数据
    ExampleActions.getA();
  }

  componentWillUnmount() {
    //卸载监听函数
    ExampleStore.removeChangeListener(this._onExampleChange);
  }

  render() {

   const {a,b,c} = this.state;

   //此处省略其他业务代码
   ....

   return (

   //此处省略其他业务代码
   ....

   );
  }

  //定义回调函数,从store层获取最新值,更新state状态,并进行相关操作(注意:this.setState() 是异步方法,所以添加回 
  //调函数作为第二个参数才能有效)
  _onExampleChange = () => {
    this.setState(getExampleState(), () => {
      //此处省略其他业务代码
      ....
    });
  };

  //此处省略其他业务代码
 ....

}

export default ExamplePage;
  • Dispatch
//AppDispatcher.js

//引入flux的Dispatcher方法
var Dispatcher = require('flux').Dispatcher;

//实例化Dispatcher对象暴露给acion层和store层使用
module.exports = new Dispatcher();
  • ActionTypes
//ActionTypes.js

import keyMirror from 'keymirror';

export default keyMirror({

  //在此文件中提前定义好所有的ActionType,方便store层和action层调用,免除多次声明,方便管理
  EXAMPLE_UPDATE: null,
  EXAMPLE_CLEAR: null
  //此处省略其他业务代码
  ....

})
阅读 473更新于 2018-11-21

推荐阅读
目录