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的理念请看博主的其它文章
React 实践记录 04 Flux demo的更多相关文章
- React 实践记录 02 Flux introduction
Introduction 本文组成: React 官方文档翻译 相关实践心得. 内容上是Flux的介绍,例子将会在以后写出. 一旦稍微多了解一点React,很难避免听到Flux这个名词. Flux是一 ...
- React 实践记录 01 组件开发入门
Introduction 本文组成: Ryan Clark文章Getting started with React的翻译. 博主的实践心得. React由Facebook的程序员创建,是一个非常强大的 ...
- React 实践记录 03 React router
Introduction 本文主要参考了react router 的官方文档. React Router是一套完整的配合React的路由解决方案,可能你已经知道前端路由,或者知道后端有路由的概念,如下 ...
- Flux demo
Flux demo Introduction flux应用架构如下图所示,本文并不是讲述怎么立即做一个酷炫的应用,而是讲述如何依照这种框架,来进行代码的组织.我们先把这个流程转述为文字:抛开与webA ...
- Ionic3项目实践记录
Ionic3首次项目实践记录 标签(空格分隔): Angular Ionic Ionic3踩坑 1. 路由懒加载(lazy load) 如果设置了懒加载,就必须全部懒加载(包括TabsPage),否则 ...
- React实践
React实践(一) 该实践取自官方教程:https://github.com/reactjs/react-tutorial 主要是自实现的过程以及一些心得体会 该实践是实现一个评论框. 一个展示 ...
- React 实践项目 (二)
React在Github上已经有接近70000的 star 数了,是目前最热门的前端框架.而我学习React也有一段时间了,现在就开始用 React+Redux 进行实战! React 实践项目 (一 ...
- React 实践项目 (三)
React在Github上已经有接近70000的 star 数了,是目前最热门的前端框架.而我学习React也有一段时间了,现在就开始用 React+Redux 进行实战! 上回说到使用Redux进行 ...
- React 实践项目 (五)
React在Github上已经有接近70000的 star 数了,是目前最热门的前端框架.而我学习React也有一段时间了,现在就开始用 React+Redux 进行实战! React 实践项目 (一 ...
随机推荐
- ORA-12547: TNS:lost contact
碰到这个ORA-12547: TNS:lost contact的问题,翻了很多资料和METALINK,总结了一下原因: 1 是由于rpm包没有安装,对于我们的生产环境,此包是安装的. admin@p1 ...
- Snmp在Windows下的实现----WinSNMP编程原理
在Windows 下实现SNMP协议的编程,可以采用Winsock接口,在161,162端口通过udp传送信息.在Windows 2000中,Microsoft已经封装了SNMP协议的实现,提供了一套 ...
- HUD1686(KMP入门题)
Oulipo Time Limit: 3000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others)Total Subm ...
- React.js:template
ylbtech-React.js: 1.返回顶部 2.返回顶部 3.返回顶部 4.返回顶部 5.返回顶部 6.返回顶部 作者:ylbtech出处:http://ylbtec ...
- ceph学习之PG
PG的计算公式: 整个集群PG的计算公式 Total PGs = ((Total_number_of_OSD * ) / max_replication_count) 每个POOL中PG的计算公式: ...
- ajax展示新页面同时传递参数
HTML页面部分代码: <div id="course" hidden></div> HTML页面中ajax代码: var selectType=$(&qu ...
- windows安装PHP5.4+Apache2.4+Mysql5.5
windows安装PHP5.4+Apache2.4+Mysql5.5 作者:星之宇 ┊ 时间:2012-10-18 14:27 ┊ 分类: 网站技术 ┊ 阅读:1232 ┊ 评论:16 最近听说PHP ...
- Fuzzy Search
题意: 考虑模板串B和给定串A,给定K,对于模板串上给定位置j的字符,如果能在给定串上i左右K个字符内找到相同字符,则说可以匹配. 问有多少匹配. 解法: 考虑对于每一种字符分开求. 对于当前字符ch ...
- TypeScript完全解读(26课时)_12.TypeScript完全解读-高级类型(1)
12.TypeScript完全解读-高级类型(1) 高级类型中文网的地址:https://typescript.bootcss.com/advanced-types.html 创建新的测试文件 ind ...
- Flutter实战视频-移动电商-03.底部导航栏制作
03.底部导航栏制作 material是谷歌退出的 还有另外的一种:cupertino是IOS的风格 我们底部的导航栏,静态的widget是不合适的,这垃圾我们用到动态的widget 这重新改成动态的 ...