Follow me on GitHub Follow me on Twitter

React 实践记录 04 Flux demo

Introduction

flux应用架构如下图所示,本文并不是讲述怎么立即做一个酷炫的应用,而是讲述如何依照这种框架,来进行代码的组织。

我们先把这个流程转述为文字:抛开与webAPI的交互不谈,以后的文章再介绍。
flux应用的数据流是单向的,从我们之前最熟悉的React组件看起,它们构成了上图中的React Views。用户交互可以使得Action Creators创建Action,交由Dispatcher分发。根据已注册的Store信息,Dispathcer管理依赖,完成分发,而Store会触发数据改变的事件,侦听该事件的React Views即会进行Store Queries,拿到数据。
本文以完成下图的功能为例,一个可以添加item的表单。如果不套flux用的代码少的多,但是,这样的例子适合用于讲解flux而非专注于其它细节(复杂应用将更偏重于React 组件的设计,于本文中心偏离)。

源码已经上传:https://github.com/EcutDavid/fluxDemo

搭建目录,文件结构

 mkdir script && cd script 
 mkdir actions components dispatcher stores constants
 cd ..
 touch entry.js index.html webpack.config.js

关于webpack,博主的webpack系列文章已经介绍,再此,不再赘述。
安装moudles(关于moudles的选型,仁者见仁,智者见智,无需拘束于以下的例子)。

npm init 
npm install babel-loader css-loader style-loader flux react keymirror events obejct-assign --save

Dispatcher

flux中, Dispatcher是单例的,所以,直接向下面代码一样返回一个实例。之后,Action与Store都会用到它们。

script/dispatcher/dispatcher.js

var Dispatcher = require('flux').Dispatcher;

module.exports = new Dispatcher();

Action

实现一个枚举,用于定义所有的Action类型,借助于keymirror实现

script/constants/appConstants.js

var keyMirror = require('keymirror');

module.exports = new keyMirror({
  CREATE: null
});

ActionCreator要借助dispatcher来分发action。

script/actions/appActionCreator.js

"use strict"

var dispatcher = require('../dispatcher/dispatcher');
var appConstants = require('../constants/appConstants');

var appActionCreator = {
  create: function(text) {
    dispatcher.dispatch({
      actionType: appConstants.CREATE,
      text: text
    });
  }
};

module.exports = appActionCreator;

Store

Store中,我们需要向dispatcher注册并处理dispatcher分发过来的action,提供接口使得view可以侦听数据变化,查询数据。

script/stores/appStore.js

"use strict"
var dispatcher = require('../dispatcher/dispatcher');
var EventEmitter = require('events').EventEmitter;
var appConstants = require('../constants/appConstants');
var assign = require('object-assign');

var CHANGE_EVENT = 'change';
var textList = [];

var appStore = assign({}, EventEmitter.prototype, {
  create: function(text){
    textList.push(text);
  },
  getAll: function() {
    return textList;
  },
  emitChange: function() {
    this.emit(CHANGE_EVENT);
  },
  addChangeListener: function(callback) {
    this.on(CHANGE_EVENT, callback);
  },
  removeChangeListener: function(callback) {
    this.removeListener(CHANGE_EVENT, callback);
  }
});

dispatcher.register(function(action) {
  switch(action.actionType) {
    case appConstants.CREATE:
      appStore.create(action.text);
      appStore.emitChange();
      break;
    default:
  }
});

Views

在view中,我们侦听store的数据变化,在用户交互时,发出action。

"use strict"
var React = require('react');
require('../../style/main.css');
var appActionCreator = require('../actions/appActionCreator');
var appStore = require('../stores/appStore');

var App = React.createClass({
  componentDidMount: function(){
    appStore.addChangeListener(this._onChange);
  },
  componentWillUnmount: function(){
    appStore.removeChangeListener(this._onChange);
  },
  _onChange: function(){
    var arr = appStore.getAll();
    this.setState({'infoList': arr});
  },
  getInitialState:function(){
    var arr = appStore.getAll();
    return({'infoList': arr});
  },
  add: function(){
    appActionCreator.create(React.findDOMNode(this.refs.textArea).value);
  },
  render: function(){
    var textList = this.state.infoList.map(function(item){
      return <p>{item}</p>;
    });
    return(
      <div className="container">
        <input ref="textArea" type="text"></input>
        <button className="button" onClick={this.add}>add</button>
        {textList}
      </div>
    );
  }
});

module.exports = App;

entry.js

var React = require('react');
var App = require('./script/components/app');

React.render(<App />, document.body);

index.html

<!DOCTYPE html>
<html>
  <head>
    <meta charset="utf-8">
    <title></title>
  </head>
  <body>
    <script src="bundle.js"></script>
  </body>
</html>

效果:

dispatcher还可以管理sotre之间的依赖, 借助react,我们还可以开发很多易维护的前端组件。
本文是一个完整的flux应用的例子,侧重的是代码,flux的理念请看博主的其它文章 😃

posted @ 2015-09-04 15:43  官文祥  阅读(1393)  评论(4编辑  收藏  举报