从Flux到Redux是状态管理工具的演变过程,但两者还是有细微的区别的。但是最核心的都还是观察者模式的应用。

一、Flux

1. Flux的处理逻辑

通俗来讲,应用的状态被放到了store中,组件是store状态的一个映射,用户通过事件触发action,再通过Dispatcher根据不同的actionType进行分发,并做不同的逻辑处理,但核心都是通过直接改变store的状态,再触发emitChange间接改变组件中的数据。(后面会上代码)

从代码层面来讲,store中的数据通过EventEmitter注册监听,并通知引入此store的组件状态变化,view中的数据实时通过store获取,action中则是通过AppDispatcher分发,而注册后的AppDispatcher则根据对应的actionTypes做不通的逻辑处理。

常规方法使用Flux需要引入的库有:Dispatcher,EventEmitter

2. Flux的劣势:

1.Flux可以有多个store,而当逻辑复杂时,多个store的依赖会非常繁琐。异步操作也不是很友好。

2. 难以进行服务端渲染,同构成本较高。

3. store混杂了处理逻辑与状态。

3. Flux项目的关联核心代码:

js/countPanel.js

类的构造函数初始化store的数据:

constructor (props) {
  super(props);
  this.state = {max: 15, fluxData: CounterValues};
  this.setMax = this.setMax.bind(this);
  this.totalChange = this.totalChange.bind(this);
  this.fluxTest = this.fluxTest.bind(this);
}

在事件中调用action

<button onClick={this.fluxTest}>click flux</button>

fluxTest () {
increment();
}

./Action.js

import * as ActionTypes from './ActionTypes.js';
import AppDispatcher from './AppDispatcher.js'; export const increment = (counterCaption) => {
  AppDispatcher.dispatch({
    type: ActionTypes.INCREMENT,
    counterCaption: counterCaption
  })
} export const decrement = (counterCaption) => {
  AppDispatcher.dispatch({
    type: ActionTypes.DECREMENT,
    counterCaption: counterCaption
  })
}

./AppDispatcher.js

import {Dispatcher} from 'flux';
import * as ActionTypes from './ActionTypes.js';
import CounterStore from './store/CounterStore.js';
let AppDispatcher = new Dispatcher(); AppDispatcher.register((actions) => {
  if (actions.type === ActionTypes.INCREMENT) {
    // CounterValues[actions.counterCaption]++;
    CounterStore.doChange('First', 1000)
    CounterStore.emitChange();
  } else if (actions.type === ActionTypes.DECREMENT) {
    // doSomthing
  }
})
export default AppDispatcher;

./store/CounterStore.js

通过EventEmitter(观察者模式最典型的应用)注册数据监听与处理:

import {EventEmitter} from 'events';
const CounterValues = {
  First: 0,
  Second: 10,
  Third: 30
}
const CounterStore = Object.assign({}, EventEmitter.prototype, {
  doChange (counterKey, CounterVal) {
    CounterValues[counterKey] = CounterVal;
  },
  getCounterValues: function () {
    return CounterValues;
  },
  emitChange: function () {
    this.emit('change');
  },
  addChangeListener: function (callBack) {
    this.on('change', callBack);
  },
  removeChangeListener: function (callBack) {
    this.removeChangeListener('change', callBack)
  }
})
export {CounterValues};
export default CounterStore;

二、Redux

1. Redux的三条原则:

(1)唯一数据源

(2)保持状态只读

(3)通过纯函数改变数据

ps: 纯函数:1.不得改写参数 2. 不得调用系统的IO 3. 不能调用Date.now()或Math.random()等方法,因为每次获取的结果都不同。

2. Redux的逻辑处理

与Flux的区别在于:

(1)Flux中对action的处理没有返回值,只是通过Dispatcher分发动作,由Dispatcher的注册函数中做逻辑处理;而Redux中则取消了Dispatcher对象,action只是通过store的dispatch方法提交动作,再由store注册的reducer根据对应的ActionTypes做逻辑处理。

(2)Flux中的逻辑处理是直接对现有的state做处理,而Redux则是通过纯函数进行处理,在原有的state基础上返回新生成的state,不会对原有数据产生副作用。

3. Redux实际使用的核心代码:

./counter.js

在事件处理函数中通过store.dispatch分发动作:

onIncrement() {
store.dispatch(Actions.increment(this.props.caption));
}  

通过subscribe进行监听:

componentDidMount() {
store.subscribe(this.onChange);
} componentWillUnmount() {
store.unsubscribe(this.onChange);
}

./action.js

对应的dispatch处理函数中,返回一个action对象:

export const increment = (counterCaption) => {
return {
type: ActionTypes.INCREMENT,
counterCaption: counterCaption
};
};

./reducer.js

通过纯函数处理对应的action

export default (state, action) => {
const {counterCaption} = action;
switch (action.type) {
case ActionTypes.INCREMENT:
return {...state, [counterCaption]: state[counterCaption] + 1};
case ActionTypes.DECREMENT:
return {...state, [counterCaption]: state[counterCaption] - 1};
default:
return state
}
}

./store.js

通过createStore将reducer与store数据联系起来

import {createStore} from 'redux';
import reducer from './reducer.js'; const initValues = {
'First': 0,
'Second': 10,
'Third': 20
}; const store = createStore(reducer, initValues); export default store;

  

  

从Flux到Redux详解单项数据流的更多相关文章

  1. redux详解

    redux介绍 学习文档:英文文档,中文文档,Github redux是什么 redux是一个独立专门用于做状态管理的JS库(不是react插件库),它可以用在react, angular, vue等 ...

  2. ReactNative之Redux详解

    用redux有一段时间了,感觉还是有必要把其相关的知识点系统的总结一下的,毕竟好记性不如烂笔头.上篇博客更新了关于<ES6中的迭代器.Generator函数以及Generator函数的异步操作& ...

  3. 九、小程序 Redux详解与在小程序中怎么使用(action和reducers)

    什么是Redux ​ Redux我们可以把它理解成一个状态管理器,可以把状态(数据)存在Redux中,以便增.删.改.例如: 从服务器上取一个收藏列表,就可以把取回来的列表数据用Redux管理,多个页 ...

  4. 详解 Node + Redux + MongoDB 实现 Todolist

    前言 为什么要使用 Redux? 组件化的开发思想解放了繁琐低效的 DOM 操作,以 React 来说,一切皆为状态,通过状态可以控制视图的变化,然后随着应用项目的规模的不断扩大和应用功能的不断丰富, ...

  5. 《TCP/IP详解卷1:协议》第19章 TCP的交互数据流-读书笔记

    章节回顾: <TCP/IP详解卷1:协议>第1章 概述-读书笔记 <TCP/IP详解卷1:协议>第2章 链路层-读书笔记 <TCP/IP详解卷1:协议>第3章 IP ...

  6. React-Navigation与Redux整合详解

    本文转自:文章地址:http://blog.csdn.net/u013718120/article/details/72357698 继react-navigation发布已经过去半年的时间,想必Re ...

  7. redux和react-redux的使用详解

    我自己的理解redux就跟vue中的vuex差不多,都是数据管理器,话不多说,我们从经典的计数器案例开始讲解 使用redux实现计数器 创建如下的react项目,我习惯把每一个模块分块,才有这么多文件 ...

  8. Vue组件通信方式全面详解

    vue组件通信方式全面详解 众所周知,Vue主要思想就是组件化开发.因为,在实际的项目开发中,肯定会以组件的开发模式进行.形如页面和页面之间需要通信一样,Vue 组件和组件之间肯定也需要互通有无.共享 ...

  9. 【原创】Redux 卍解

    Redux 卍解 Redux - Flux设计模式的又一种实现形式. 说起Flux,笔者之前,曾写过一篇<ReFlux细说>的文章,重点对比讲述了Flux的另外两种实现形式:『Facebo ...

随机推荐

  1. 【转】 Pro Android学习笔记(七三):HTTP服务(7):AndroidHttpClient

    文章转载只能用于非商业性质,且不能带有虚拟货币.积分.注册等附加条件,转载须注明出处:http://blog.csdn.net/flowingflying/ 不知道此文是否是这个系列中最短的一篇.我们 ...

  2. JAVA 编程思想三

    1:JAVA可变参数? 参数个数不确定,但是类型确定: 可变参数位于最后一项,只支持一个可变参数: public void funciton1(int a, String ...args) { for ...

  3. uva 512

    1. 问题 不知道怎么存储操作 看代码注释,else if等 2. 代码 #include <iostream> #include <stdio.h> #include < ...

  4. 请问两个div之间的上下距离怎么设置

    转自:https://zhidao.baidu.com/question/344630087.html 楼上说的是一种方法,yanzilisan183 <div style="marg ...

  5. shell自动收集服务器硬件系统信息

    shell自动收集服务器硬件系统信息,插入数据库并通过web页面显示. 一,shell自动收集服务器硬件系统信息,插入数据库.#centos 7操作系统下 #!/bin/bash #auto get ...

  6. 菜鸟级的Git与GitHub使用总结(转)

    菜鸟级的Git与GitHub使用总结 原创 2016年12月01日 14:58:30 1792 前言 这几天一直在折腾学习Git和GitHub的使用.几天下来,在网上查阅了大量的资料,总算有一些成果. ...

  7. Entity Framework Code-First(9.7):DataAnnotations - Table Attribute

    DataAnnotations - Table Attribute: Table attribute can be applied to a class. Default Code-First con ...

  8. Spring入门第二十五课

    使用具名参数 直接看代码: db.properties jdbc.user=root jdbc.password=logan123 jdbc.driverClass=com.mysql.jdbc.Dr ...

  9. LightOJ 1311 Unlucky Bird (物理题)

    题意:有点长,意思是说有一个鸟,在两列火车之间不停的来回飞,两列相距为d时,都开始减速,直到最后停止下来,正好是相距0米, 现在给定两列车的速度和减速时的加速度,和鸟的速度求 d 和鸟飞过的路程. 析 ...

  10. POJ 2398 Toy Storage (叉积判断点和线段的关系)

    题目链接 Toy Storage Time Limit: 1000MS   Memory Limit: 65536K Total Submissions: 4104   Accepted: 2433 ...