实现一个简单的flux
前言
众所周知,React跟Flux是一对好基友。
其中,市场流行的Flux有Redux,Mobx,Reflux。
其中,用法最简单的是Reflux。
其数据流思路如下:
+---------+ +--------+ +-----------------+
¦ Actions ¦------>¦ Stores ¦------>¦ View Components ¦
+---------+ +--------+ +-----------------+
^ ¦
+--------------------------------------+
我们能否再减少其数据流路径?如下:
+--------+ +-----------------+
¦ Stores ¦------>¦ View Components ¦
+--------+ +-----------------+
^ ¦
----------------------+
两个字,可以。
需求分析
- 集成Actions的功能到Stores。从而拿掉单独的Actions。
- 集成组件的State和Store在一起。
- 跨组件通信依赖其Store。
撸函数
这意味着我们的createStore
是一个工厂函数。
用来生产每一个React组件实例对应的Store实例。
function isObject(obj) {
return Object.prototype.toString.call(obj) == '[object Object]';
}
function extend(obj) {
if (!isObject(obj)) {
return obj;
}
for (let i = 1, length = arguments.length; i < length; i++) {
let source = arguments[i];
for (let prop in source) {
if (Object.getOwnPropertyDescriptor && Object.defineProperty) {
let propertyDescriptor = Object.getOwnPropertyDescriptor(source, prop);
Object.defineProperty(obj, prop, propertyDescriptor);
} else {
obj[prop] = source[prop];
}
}
}
return obj;
}
function createStore(definition={}) {
function Store() {
let t = this;
t.data = null;
extend(t, definition);
t.trigger = function () {
this.setState({});
}
}
let store = new Store();
return store;
};
isObject
和extend
这两个函数按下不表。
其中,extend
函数是用来对象合并,该函数某部位依赖isObject
。((__) 嘻嘻……)
createStore
函数产出的实例内部
data
作为组件实例的store。trigger
作为更新组件实例的方法。
万事具备,只欠东风。
接下来就是用connect
函数把组件实例和Store实例连接在一起。
function connect(listenable, context) {
if(!isObject(listenable)){
throw new Error('connect function\'s argument is not a object');
}
return {
componentDidMount() {
context = context || this;
listenable.trigger = listenable.trigger.bind(context);
},
componentWillUnmount() {
listenable.trigger = null;
}
};
}
借用React组件生命周期,在其componentDidMount
阶段,
改变Store实例的trigger
上下文,使其指向React组件实例,
从而方便trigger
调用React组件实例的setState
方法。
全套代码如下:
撸Demo
- Samflux.js
function isObject(obj) {
return Object.prototype.toString.call(obj) == '[object Object]';
}
function extend(obj) {
if (!isObject(obj)) {
return obj;
}
for (let i = 1, length = arguments.length; i < length; i++) {
let source = arguments[i];
for (let prop in source) {
if (Object.getOwnPropertyDescriptor && Object.defineProperty) {
let propertyDescriptor = Object.getOwnPropertyDescriptor(source, prop);
Object.defineProperty(obj, prop, propertyDescriptor);
} else {
obj[prop] = source[prop];
}
}
}
return obj;
}
exports.createStore = function (definition={}) {
function Store() {
let t = this;
t.data = null;
extend(t, definition);
t.trigger = function () {
this.setState({});
}
}
let store = new Store();
return store;
};
exports.connect = function (listenable, context) {
if(!isObject(listenable)){
throw new Error('connect function\'s argument is not a object');
}
return {
componentDidMount() {
context = context || this;
listenable.trigger = listenable.trigger.bind(context);
},
componentWillUnmount() {
listenable.trigger = null;
}
};
}
- store.js
const Samflux = require('./Samflux.js');
const Store = Samflux.createStore({
data:'old data',
onSetData: function(){
this.data = 'new data';
this.trigger();
},
});
module.exports = Store;
- SamfluxTest.js
const Store = require('./store.js');
const Samflux = require('./Samflux.js');
const reactMixin = require('react-mixin');
const React = window.React;
require('./SamfluxTest.less');
class Test extends React.Component {
constructor(props) {
super(props);
this.state = {
};
}
setData(){
Store.onSetData();
}
render() {
const me = this;
return (<div className="SamfluxTest" onClick={me.setData.bind(this)}><span>{Store.data}</span></div>);
}
}
reactMixin.onClass(Test, Samflux.connect(Store));
module.exports = Test;
实现一个简单的flux的更多相关文章
- 响应式编程笔记三:一个简单的HTTP服务器
# 响应式编程笔记三:一个简单的HTTP服务器 本文我们将继续前面的学习,但将更多的注意力放在用例和编写实际能用的代码上面,而非基本的APIs学习. 我们会看到Reactive是一个有用的抽象 - 对 ...
- 哪种缓存效果高?开源一个简单的缓存组件j2cache
背景 现在的web系统已经越来越多的应用缓存技术,而且缓存技术确实是能实足的增强系统性能的.我在项目中也开始接触一些缓存的需求. 开始简单的就用jvm(java托管内存)来做缓存,这样对于单个应用服务 ...
- 在Openfire上弄一个简单的推送系统
推送系统 说是推送系统有点大,其实就是一个消息广播功能吧.作用其实也就是由服务端接收到消息然后推送到订阅的客户端. 思路 对于推送最关键的是服务端向客户端发送数据,客户端向服务端订阅自己想要的消息.这 ...
- ASP.NET Aries 入门开发教程2:配置出一个简单的列表页面
前言: 朋友们都期待我稳定地工作,但创业公司若要躺下,也非意念可控. 若人生注定了风雨飘摇,那就雨中前行了. 最机开始看聊新的工作机会,欢迎推荐,创业公司也可! 同时,趁着自由时间,抓紧把这系列教程给 ...
- 计算机程序的思维逻辑 (60) - 随机读写文件及其应用 - 实现一个简单的KV数据库
57节介绍了字节流, 58节介绍了字符流,它们都是以流的方式读写文件,流的方式有几个限制: 要么读,要么写,不能同时读和写 不能随机读写,只能从头读到尾,且不能重复读,虽然通过缓冲可以实现部分重读,但 ...
- 如何开发一个简单的HTML5 Canvas 小游戏
原文:How to make a simple HTML5 Canvas game 想要快速上手HTML5 Canvas小游戏开发?下面通过一个例子来进行手把手教学.(如果你怀疑我的资历, A Wiz ...
- CSharpGL(24)用ComputeShader实现一个简单的图像边缘检测功能
CSharpGL(24)用ComputeShader实现一个简单的图像边缘检测功能 效果图 这是红宝书里的例子,在这个例子中,下述功能全部登场,因此这个例子可作为使用Compute Shader的典型 ...
- CSharpGL(23)用ComputeShader实现一个简单的ParticleSimulator
CSharpGL(23)用ComputeShader实现一个简单的ParticleSimulator 我还没有用过Compute Shader,所以现在把红宝书里的例子拿来了,加入CSharpGL中. ...
- 应用OpenMP的一个简单的设计模式
小喵的唠叨话:最近很久没写博客了,一是因为之前写的LSoftmax后馈一直没有成功,所以在等作者的源码.二是最近没什么想写的东西.前两天,在预处理图片的时候,发现处理200w张图片,跑了一晚上也才处理 ...
随机推荐
- LNMP的并发配置和资源分配
PHP程序性能如何?程序的并发可以达到多少?程序的瓶颈在哪儿?为了满足业务需求应该购买多少台服务器?负载均衡中php应用服务器需要多少台? LNMP中的N是nginx充当Web Server 内容的分 ...
- spark与kafka集成进行实时 nginx代理 这种sdk埋点 原生日志实时解析 处理
日志格式202.108.16.254^A1546795482.600^A/cntv.gif?appId=3&areaId=8213&srcContId=2535575&area ...
- Kali linux apt-get update 失败,无release……(最有效)
设置源 编辑 /etc/apt/sources.list nano /etc/apt/sources.list 清空文件内所有内容后添加 deb http://mirrors.ustc.edu.cn/ ...
- Java中高级面试必问之多线程TOP50(含答案)
以下为大家整理了今年一线大厂面试被问频率较高的多线程面试题,由于本人的见识局限性,所以可能不是很全面,也欢迎大家在后面留言补充,谢谢. 1.什么是线程? 2.什么是线程安全和线程不安全? 3.什么是自 ...
- Python进阶【第一篇】:Python简介
Python简介 1.Python的由来 Python是著名的“龟叔”Guido van Rossum在1989年圣诞节期间,为了打发无聊的圣诞节而编写的一个编程语言. 2.C 和 Python.Ja ...
- Eloquent JavaScript #08# Bugs and Errors
索引 Notes strict mode js类型 js测试 Debugging Exceptions finally 异常分支 Exercise Retry The locked box Notes ...
- php使用phpexcel导出文件
php使用phpexcel导出文件 首先需要去官网https://github.com/PHPOffice/PHPExcel/下载PHPExcel 代码如下: <?php date_defaul ...
- Fiddler(三)Fiddler 报错creation of the root certificate was not successful
打开CMD,找到Fiddler所在目录,我这里是把汉化版的解压在了桌面,所以通过CMD进入桌面下的Fiddler文件夹. 执行命令 makecert.exe -r -ss my -n -h -cy a ...
- markdown 换行
基本语法 basic grammar line break
- Redhat普通用户如何使用管理员权限
作为一个普通用户, 很多地方收到权限的控制, 下面展示sudoers大法, 主要就是sudo的问题了. 下面的是我的普通用户lee 还没有授权之前是这样的 开始授权 切换到root用户, 修改sudo ...