Flux框架

Flux用来解决React在结构上的问题,从Flux也衍生了Redux,Flux也类似MVC这一类的架构,Flux最大特点就是单向数据流动

1.基本概念

flux流程

这是Flux在GitHub上文档中所提供的流程展示图,里面有四个核心的东西

Action:动作,视图层发出的动作,类似事件
Dispatcher:派发器,接受Action,全局唯一,相当于C
Store:存储层,相当于M,数据变化,会让View层对应修改,负责存储和处理数据相关逻辑
View:视图层,相当于V

整个流程如下
1.从用户操作页面开始,发出Action
2.Dispatcher接受Action,然后派发Action,找到对应的Store
3.Store进行更新,发出一个change事件
4.页面接受change,更新界面
这就是一个完整单向的数据流动过程,任何过程都不会发生双向数据流动

2.Action

整个过程从Action开始,Action是一个JS对象,用来描述我们要干什么,需要什么样的数据,可以写一个Action.js文件,在这个文件里,对所有Action进行汇总,Flux只要加一个新的功能,就要对应加一个Action类型,这就像MVC中如果要添加新的功能添加新的Controller一样,在Flux里,就是添加新的Action.

export const addNum = (result) => {
  AppDispatcher.dispatch({
    actionName: "add",
    counterCaption: result
  });
};

定一个对外使用的函数,这个函数目的就是点击按钮+1,通过页面点击事件发出的Action而,触发事件的View,还是正常绑定事件,只是在对应事件的具体实现,需要找到Action里对应的函数,然后进行调用

import * as Actions from '../Actions.js';
class Son extends Component {
  onClickAddButton() {
    Actions.addNum("add");
  }
}

当然我简化了整个过程,这样就完成了事件的触发,接下来开始执行回调函数里面的内容了,首先我们引入了AppDispatcher.js文件,它创造了一个唯一的Dispatcher对象,类似于单例,通过它来发送和接管Action.
AppDispatcher.dispatch相当于发送了一个消息,这个消息包含了需要发送的内容,也就是需要传的值,一般都会有actionName这样的字段,标明当前Action代表了什么样的操作,名随便,然后其他字段可以对应要传的值.

3.Dispatcher

在代码里,Dispatcher对应的AppDispatcher.js不需要写什么,就返回一个默认的Dispatcher对象

import {Dispatcher} from 'flux';
export default new Dispatcher();

Dispatcher提供的API也不是很多,一共5个方法
1.dispatch:用来发送消息,包含要传的数据,Action的参数
2.register(function callback):注册一个接受消息的接收器,可以接受到dispatch发送的消息,Stores自己需求,完成对应数据的操作
3.unregister:跟注册相应的方法,移除毁掉函数
4.isDispatching:boolean类型的返回值,是否目前正在调用的dispatcher
5.waitFor(array<string> ids):有的时候在一个过程中注册了几个监听器,但是就怕出现意外,因为顺序上的混乱造成bug,所以为了避免这个问题就可以使用waitFor来控制.这个方法需要一个数组,这个数组里的元素都是dispatchToken,也就是注册的监听器,会告诉Dispatcher当前的处理必须暂停,直到这些已经注册的监听都执行结束才会继续,这样就避免了因为顺序而造成的不必要的错误
注册这部分代码要写在Stores

import AppDispatcher from '../AppDispatcher.js';
CounterStore.dispatchToken = AppDispatcher.register((action) => {
  if (action.actionName === "add") {
    counterValues[action.counterCaption] ++;
  } else if (action.actionName === "sub") {
    counterValues[action.counterCaption] --;
  }
});

CounterStore是一个计数器类,添加了dispatchToken用来保存注册的监听器,action用来接收发射器传递的数据,根据对应的action事件类型进行对应的操作,而且这个文件如果被其他文件inport之后,可以通过CounterStore.dispatchToken找到对应的监听器,这样就能用在waitFor这个方法里了

4.Store

Store用来存储应用对应状态,根据接收dispatch对应的状态,更改View的显示状态,而监听整个变化的过程就需要使用EventEmitter来帮助实现.EventEmitter的核心功能就是事件触发和事件监听.

import {EventEmitter} from 'events';
const CounterStore = Object.assign({}, EventEmitter.prototype, {
    getCounterValues: function() {
        return counterValues;
    },
    emitChange: function() {
        this.emit('changed');
    },
    addChangeListener: function(callback) {
        this.on('changed', callback);
    },
    removeChangeListener: function(callback) {
        this.removeListener('changed', callback);
    }
});

引完库文件之后,通过代码拷贝创建了一个CounterStore对象,而拷贝的内容就是EventEmitter.prototype,这样就可以使用prototype提供的响应方法.
1.getCounterValues函数是为了获取当前计数器初始值的,这个跟EventEmitter无关.
2.emitChange:这个函数调用了emit,这是EventEmitter提供的功能,用来广播一个特定事件,第一个参数是事件名称,字符串.这个方法是一个做汇总的模块用的.
3.addChangeListener:添加监听,用EventEmitter提供的on进行绑定,第一个参数是事件名称,第二个参数是对应的回调函数,这个函数将在View界面传过来
4.removeChangeListener:移除,跟on功能想法,但是删除对应的回调函数要和添加的时候是同一个,这跟JQ移除事件的要求是相同的

5.View

通过了Store,就要通过View来具体呈现,

import CounterStore from '../stores/CounterStore.js';
class Son extends Component {
    componentDidMount() {
        CounterStore.addChangeListener(this.onChange);
    }
    componentWillUnmount() {
        CounterStore.removeChangeListener(this.onChange);
    }
    onChange() {
        // 更改数据内容
    }
}

在装载和摧毁两个周期调用监听的函数,同时设置回调函数onChange,onChange里就对应了对数据的操作.在View的时候,只能使用Store的get方法,而Store也没有set方法就是为了防止V直接去修改M上的数据,如果想改Store的数据,可以在发送action,重新一个新的流程,避免了传统MVC数据上的混乱

整个过程从点击按钮开始,到最后数字+1结束,完成了一个闭合的操作

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 214,951评论 6 497
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 91,606评论 3 389
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 160,601评论 0 350
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 57,478评论 1 288
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 66,565评论 6 386
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 50,587评论 1 293
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 39,590评论 3 414
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 38,337评论 0 270
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 44,785评论 1 307
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 37,096评论 2 330
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 39,273评论 1 344
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 34,935评论 5 339
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 40,578评论 3 322
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 31,199评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,440评论 1 268
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 47,163评论 2 366
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 44,133评论 2 352

推荐阅读更多精彩内容

  • 原文 简介 RxFlux 是一个使用 RxJava1 实现 Flux模式 的轻量级框架,RxFlux 仅仅提供 F...
    coolfireApy阅读 1,328评论 0 1
  • ##Flux与面向组件化开发首先要明确的是,Flux并不是一个前端框架,而是前端的一个设计模式,其把前端的一个交互...
    吴小蛆阅读 315评论 0 0
  • 原教程内容详见精益 React 学习指南,这只是我在学习过程中的一些阅读笔记,个人觉得该教程讲解深入浅出,比目前大...
    leonaxiong阅读 2,829评论 1 18
  • Android项目做了不少,难免遇到因为在项目架构上设计不合理或者根本没有形成统一的编程思想,导致各种意外的情况出...
    Forrest32阅读 5,990评论 11 34
  • 翻译:莫铭原文地址:Flux-In Depth Overview Flux是Facebook用来构建客户端web应...
    莫铭阅读 2,100评论 0 0