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/fluxDemocss
mkdir script && cd script mkdir actions components dispatcher stores constants cd .. touch entry.js index.html webpack.config.js
关于webpack,博主的webpack系列文章已经介绍,再此,再也不赘述。
安装moudles(关于moudles的选型,仁者见仁,智者见智,无需拘束于如下的例子)。html
npm init npm install babel-loader css-loader style-loader flux react keymirror events obejct-assign --save
flux中, Dispatcher是单例的,因此,直接向下面代码同样返回一个实例。以后,Action与Store都会用到它们。前端
script/dispatcher/dispatcher.jsreact
var Dispatcher = require('flux').Dispatcher; module.exports = new Dispatcher();
实现一个枚举,用于定义全部的Action类型,借助于keymirror实现webpack
script/constants/appConstants.jsgit
var keyMirror = require('keymirror'); module.exports = new keyMirror({ CREATE: null });
ActionCreator要借助dispatcher来分发action。github
script/actions/appActionCreator.jsweb
"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中,咱们须要向dispatcher注册并处理dispatcher分发过来的action,提供接口使得view能够侦听数据变化,查询数据。npm
script/stores/appStore.jsbabel
"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: } });
在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;
var React = require('react'); var App = require('./script/components/app'); React.render(<App />, document.body);
<!DOCTYPE html> <html> <head> <meta charset="utf-8"> <title></title> </head> <body> <script src="bundle.js"></script> </body> </html>
效果:
dispatcher还能够管理sotre之间的依赖, 借助react,咱们还能够开发不少易维护的前端组件。 本文是一个完整的flux应用的例子,侧重的是代码,flux的理念请看博主的其它文章 :)