实现一个简单的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张图片,跑了一晚上也才处理 ...
随机推荐
- 转:判断Caps Lock键是否打开,如果打开则关闭
using System; using System.Collections.Generic; using System.ComponentModel; using System.Data; usin ...
- localStorage单页面及不同页面监听变动
分析 H5本地存储有两个API,一个是Web Storage,还有一个是Web SQL.不管是哪一个,都是基于JavaScript语言来使用,而Web Storage提供了两种存储类型 API: s ...
- linux yum配置本地iso镜像
1.本地源配置:cdiso.repo 将iso镜像文件中所有内容复制到/public/software/cdrom 中,节点将本地yum指向此处. [root@node19 ~]# vim /etc/ ...
- 关于springMVC 传递 对象参数的问题
1.前端请求必须是 post 2.前端数据data必须做 json字符串处理 JSON.stringify(data) 3. contentType: 'application/json', 4.@ ...
- 怎样从外网访问内网Jetty?
本地安装了一个Jetty,只能在局域网内访问,怎样从外网也能访问到本地的Jetty呢?本文将介绍具体的实现步骤. 准备工作 安装并启动Jetty 默认安装的Jetty端口是8080. 实现步骤 下载并 ...
- 纯Java增删改查
//自己写的一个完整的带增删改查提交重置功能的表单代码.package com.l16.test5;import java.awt.Color;import java.awt.Container;im ...
- window JNI_CreateJavaVM启动java程序
https://blog.csdn.net/earbao/article/details/51889605 #define _CRT_SECURE_NO_WARNINGS 1 #inclu ...
- PHP优化加速之Opcache使用总结
PHP优化加速之Opcache使用总结: Opcache是一种通过将解析的PHP脚本预编译的字节码存放在共享内存中来避免每次加载和解析PHP脚本的开销,解析器可以直接从共享内存读取已经缓存的字节码,从 ...
- ==和equals的区别。
1.java中equals和==的区别 值类型是存储在内存中的堆栈(简称栈),而引用类型的变量在栈中仅仅是存储引用类型变量的地址,而其本身则存储在堆中. 2.==操作比较的是两个变量的值是否相等,对于 ...
- CRC、MD5和SHA1的区别?
什么是CRC校验?CRC即循环冗余校验码:是数据通信领域中最常用的一种查错校验码,其特征是信息字段和校验字段的长度可以任意选定.循环冗余检查(CRC)是一种数据传输检错功能,对数据进行多项式计算,并将 ...