前言

众所周知,React跟Flux是一对好基友。

其中,市场流行的Flux有Redux,Mobx,Reflux。

其中,用法最简单的是Reflux。

其数据流思路如下:

+---------+       +--------+       +-----------------+
¦ Actions ¦------>¦ Stores ¦------>¦ View Components ¦
+---------+ +--------+ +-----------------+
^ ¦
+--------------------------------------+

我们能否再减少其数据流路径?如下:

 +--------+       +-----------------+
¦ Stores ¦------>¦ View Components ¦
+--------+ +-----------------+
^ ¦
----------------------+

两个字,可以。

需求分析

  1. 集成Actions的功能到Stores。从而拿掉单独的Actions。
  2. 集成组件的State和Store在一起。
  3. 跨组件通信依赖其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;
};

isObjectextend这两个函数按下不表。

其中,extend函数是用来对象合并,该函数某部位依赖isObject。((__) 嘻嘻……)

createStore函数产出的实例内部

  1. data作为组件实例的store。
  2. 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的更多相关文章

  1. 响应式编程笔记三:一个简单的HTTP服务器

    # 响应式编程笔记三:一个简单的HTTP服务器 本文我们将继续前面的学习,但将更多的注意力放在用例和编写实际能用的代码上面,而非基本的APIs学习. 我们会看到Reactive是一个有用的抽象 - 对 ...

  2. 哪种缓存效果高?开源一个简单的缓存组件j2cache

    背景 现在的web系统已经越来越多的应用缓存技术,而且缓存技术确实是能实足的增强系统性能的.我在项目中也开始接触一些缓存的需求. 开始简单的就用jvm(java托管内存)来做缓存,这样对于单个应用服务 ...

  3. 在Openfire上弄一个简单的推送系统

    推送系统 说是推送系统有点大,其实就是一个消息广播功能吧.作用其实也就是由服务端接收到消息然后推送到订阅的客户端. 思路 对于推送最关键的是服务端向客户端发送数据,客户端向服务端订阅自己想要的消息.这 ...

  4. ASP.NET Aries 入门开发教程2:配置出一个简单的列表页面

    前言: 朋友们都期待我稳定地工作,但创业公司若要躺下,也非意念可控. 若人生注定了风雨飘摇,那就雨中前行了. 最机开始看聊新的工作机会,欢迎推荐,创业公司也可! 同时,趁着自由时间,抓紧把这系列教程给 ...

  5. 计算机程序的思维逻辑 (60) - 随机读写文件及其应用 - 实现一个简单的KV数据库

    57节介绍了字节流, 58节介绍了字符流,它们都是以流的方式读写文件,流的方式有几个限制: 要么读,要么写,不能同时读和写 不能随机读写,只能从头读到尾,且不能重复读,虽然通过缓冲可以实现部分重读,但 ...

  6. 如何开发一个简单的HTML5 Canvas 小游戏

    原文:How to make a simple HTML5 Canvas game 想要快速上手HTML5 Canvas小游戏开发?下面通过一个例子来进行手把手教学.(如果你怀疑我的资历, A Wiz ...

  7. CSharpGL(24)用ComputeShader实现一个简单的图像边缘检测功能

    CSharpGL(24)用ComputeShader实现一个简单的图像边缘检测功能 效果图 这是红宝书里的例子,在这个例子中,下述功能全部登场,因此这个例子可作为使用Compute Shader的典型 ...

  8. CSharpGL(23)用ComputeShader实现一个简单的ParticleSimulator

    CSharpGL(23)用ComputeShader实现一个简单的ParticleSimulator 我还没有用过Compute Shader,所以现在把红宝书里的例子拿来了,加入CSharpGL中. ...

  9. 应用OpenMP的一个简单的设计模式

    小喵的唠叨话:最近很久没写博客了,一是因为之前写的LSoftmax后馈一直没有成功,所以在等作者的源码.二是最近没什么想写的东西.前两天,在预处理图片的时候,发现处理200w张图片,跑了一晚上也才处理 ...

随机推荐

  1. php CI框架中URL特殊字符处理与SQL注入隐患

    php CI框架中URL特殊字符处理与SQL注入隐患 php CI框架中URL特殊字符有很多是不支持的,导致像c++,括号这些常用的分类,字符都无法正常显示很头痛,而在配置里增加单引号' 反斜杠\ 这 ...

  2. 吴恩达讲了干货满满的一节全新AI课,全程手写板书充满诚意非常干货

    吴恩达讲了干货满满的一节全新AI课,全程手写板书充满诚意非常干货 摘要: 目前,AI技术做出的经济贡献几乎都来自监督学习,也就是学习从A到B,从输入到输出的映射.现在,监督学习.迁移学习.非监督学习. ...

  3. Python+OpenCV图像处理(七)—— 滤波与模糊操作

    过滤是信号和图像处理中基本的任务.其目的是根据应用环境的不同,选择性的提取图像中某些认为是重要的信息.过滤可以移除图像中的噪音.提取感兴趣的可视特征.允许图像重采样等等.频域分析将图像分成从低频到高频 ...

  4. 前端框架VUE----箭头函数

    箭头函数 基本语法: ES6允许使用“箭头”(=>)定义函数 var f = a = > a //等同于 var f = function(a){ return a; } 如果箭头函数不需 ...

  5. JS 和 Jquery 的一些常用效果

    https://www.cnblogs.com/beiz/tag/%E7%BD%91%E9%A1%B5%E5%B8%B8%E8%A7%81%E6%95%88%E6%9E%9C/   北执

  6. Web开发笔记 #06# 前后端分离

    前后端分离 关于“前后端分离”的深入讨论: 如何正确理解前后端分离? Web 前后端分离的意义大吗? 在上面有看到有谈“国外it公司分工”的回答,感觉挺有意思的.大概是讲国外it公司并不分前后端,只分 ...

  7. MySQL日志详细说明

    这片博文我们会详细说明MySQL本身的日志,不包含重做日志和undo日志(这两个日志是innodb存储引擎的日志). MySQL本身的日志有以下几种(MySQL5.7版本): 错误日志 慢查询日志 通 ...

  8. scrapy 下载图片 from cuiqingcai

    import scrapy class MzituScrapyItem(scrapy.Item): # define the fields for your item here like: # nam ...

  9. 用到临时表空间的几种SQL

    用到临时表空间的几种SQL CREATE INDEX SELECT ... ORDER BY SELECT DISTINCT ... SELECT ... GROUP BY SELECT ... UN ...

  10. JDK JRE JVM的区别

    Jdk[Java Development ToolKit]就是java开发工具箱, JDK是整个JAVA的核心,里边包含了jre,它除了包含jre之外还包含了一些javac的工具类,把java源文件编 ...