前言

众所周知,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. Linux基础命令---文本编辑sed

    sed sed是一种流编辑器,用来从输入流中读取内容并完成转换,输入流可以来自一个文件,也可以来自一个管道. 此命令的适用范围:RedHat.RHEL.Ubuntu.CentOS.SUSE.openS ...

  2. golang学习笔记13 Golang 类型转换整理 go语言string、int、int64、float64、complex 互相转换

    golang学习笔记13 Golang 类型转换整理 go语言string.int.int64.float64.complex 互相转换 #string到intint,err:=strconv.Ato ...

  3. django 集合

    1,前言 socket 位于应用层和传输层之间的一个抽象层,它是一个接口. 百度的服务器(socket服务端) . 启动socket . 绑定ip和端口 . 监听 . 接收数据 . 发送数据 . 断开 ...

  4. Codeforce 513A - Game

    Two players play a simple game. Each player is provided with a box with balls. First player's box co ...

  5. SQL Server 2008 R2 常用系统函数学习

    /******************************************* * 聚合函数 *******************************************/ SEL ...

  6. 算法笔记 #007# Backtracking

    留着备用. 题目描述和代码参考:https://www.geeksforgeeks.org/8-queen-problem/ NQueenProblem(js代码): class NQueenProb ...

  7. JDK源码之Lock接口

    public interface Lock { //阻塞的获取锁,如果获取到锁,从该方法返回 void lock(); //可中断的获取锁,该方法会响应中断,在锁的获取中可以中断当前线程 void l ...

  8. centos6下jbd2进程占用大量IO处理

    刚在尝试重现一个bug时,好像在killed mysql一段时间之后,io一直很高,如下: 12:40:01 PM CPU %user %nice %system %iowait %steal %id ...

  9. Vue父子组件生命周期

    转载自:https://blog.csdn.net/a8725585/article/details/79092505 vue父子组件钩子函数触发顺序 beforeMount后mounted前构造子组 ...

  10. bzoj 4044 Virus synthesis - 回文自动机 - 动态规划

    题目传送门 需要高级权限的传送门 题目大意 要求用两种操作拼出一个长度为$n$的只包含'A','T','G','C'的字符串 在当前字符串头或字符串结尾添加一个字符 将当前字符串复制,将复制的串翻转, ...