学习笔记:Flux与Redux

一、概述

Flux和Redux 是React生态中重要的组成部分,个人觉得,它们核心功能就是将页面 和 数据+逻辑 解耦,将数据+逻辑 进一步抽象组件化。

二、Flux

Flux是一套架构模式,而不是代码框架。所谓的架构模式,是一套方法论,指导系统如何更好搭建。例如模块如何划分?模块间如何通信?Web开发中的MVC模式,其实就是架构模式。

1、四大核心部分
  • dispatcher:负责两件事,一是分发和处理Action,二是维护Store。
  • Store:数据和逻辑部分。
  • views:页面-React 组件,从 Store 获取状态(数据),绑定事件处理。
  • actions:交互封装为action,提交给Store处理。
2、架构设计
flux-overview.png
  • 【单向数据流】:Action -> Dispatcher -> Store -> View
  • 页面交互数据流,如用户点击按钮:View -> Create Action -> Dispatcher(由此进入【单向数据流】)

Flux参考

具体的Demo和用法参考一下教程,很详细了~
ReacFlux教程

三、Redux

1、什么Redux?

Redux 是 JavaScript 状态容器, 提供可预测化的状态管理。那什么是可以预测化,我的理解就是根据一个固定的输入,必然会得到一个固定的结果。
Redux是进化Flux,它是在Flux架构模式指导下生成的代码框架,也进一步进行架构约束设计。

  • Redux 的适用场景:多交互、多数据源。

2、Redux的核心思想

借用阮一峰大神的话:Redux 的设计思想很简单,就两句话。

  • 1、Web 应用是一个状态机,视图与状态是一一对应的。
  • 2、所有的状态,保存在一个对象里面。

3、Redux的架构约束

  • 对于 Store 的约束
    一个应用对应一个全局Store,可用单例模式来实现。
    Store只有 store.getState()store.dispatch()store.subscribe() 三个方法。
    初始化需要绑定 reducer函数,调用 store.dispatch方法会自动触发 reducer函数的执行。

  • 对于 State 的约束
    一个 State 对应一个应用,整个应用只有一个 State 对象,包含所有数据。整个应用只维护成一个树形state。
    State对象是只读的,最好把 State对象设成只读,不可变,即声明为const`。state的只能通过action触发生成新的state。
    如果想得到某个时点的数据,就要对 Store 生成快照。这种时点的数据集合,就叫做 State。

  • 对于 Actions 的约束
    Redux简化了Action,它就是一个单纯的包含 { type, payload, error, meta } 的对象;type 是一个常量用来标示动作类型;payload 是这个动作携带的数据。其中的 type 属性是必须的,表示 Action 的名称,其他属性可以自由设置,社区有一个规范可以参考。不允许扩展其他自定义属性字段。

  • 引入 Reducer :作用是保证State不可变,处理State数据。
    Store 收到 Action 以后,必须给出一个新的 State,这样 View 才会发生变化。这种 State 的计算过程就叫做 Reducer。

    因此,reducer函数 必须是一个纯函数。也就是说,只要是同样的输入,必定得到同样的输出。
    也就是说,一个 reducer函数 会接受 初始状态originalStateaction 两个参数,返回一个新的 state:(originalState, action) => newState

4、Redux的工作流

862C87CE-6ADA-45CF-BDC6-B84F328D8378.png
  • 单向数据流:store.dispatch(action) -> reducer(state, action) -> store.getState()
    2055834352-59daefda643b8_fix732.png

5、Redux的简单Demo

  • 实现Reducer
// state只读
const defaultState = 0;
const reducer = (state = defaultState, action) => {
  switch (action.type) {
    case 'ADD':
      return state + action.payload;
    default: 
      return state;
  }
};
  • 初始化Store,需要绑定reducer函数
import { createStore } from 'redux';
var store = createStore(reducer)
  • 获取状态State
store.getState()
  • 监听状态State
// 注册
let unsubscribe = store.subscribe(() =>
  console.log(store.getState())
);

// 销毁
unsubscribe();
  • 分发Actions
const action = {
  type: 'ADD',
  payload: 'Learn Redux'
};

store.dispatch(action);

5、Redux让开发者专注于数据流的处理。

Redux框架约束Store,封装了 订阅store.subscribe分发store.dispatch 的行为;封装了Action的动作;抽象定义了State对象。框架定义一整套完整的工作流程,开发者只需要关注于React组件页面,专注于相关业务数据流的设计和处理。

框架提供以下方式支持数据多样性。
  • 通过Actions实现数据多样性:通过action的属性字段(payload、errer、meta)传递用户自定义数据。

  • 通过State实现数据多样性:state对象只读,但是可以有多个的属性。

const initialState={
    a: data 1,
    b: data 2,
    c: data 3
}

我们可以把 Reducer 函数拆分,不同的函数负责处理不同属性,最终把它们合并成一个大的 Reducer 即可。Redux 提供了一个 combineReducers 方法,用于 Reducer 的拆分。你只要定义各个子 Reducer 函数,然后用这个方法,将它们合成一个大的 Reducer。

const reducer = combineReducers({
  a: doSomethingWithA,
  b: processB,
  c: c
})

// 等同于
function reducer(state = {}, action) {
  return {
    a: doSomethingWithA(state.a, action),
    b: processB(state.b, action),
    c: c(state.c, action)
  }
}

四、中间件技术,让Redux支持异步

Redux从生成action,dispatch action,生成新的state,页面更新,这一工作流是同步的。
实际开发中,需要异步的场景,redux如何支持呢? 这需要用到中间件技术。

  • 什么是中间件?
    通俗理解,就是额外增加一层中间层,这一层单独处理一组通用的逻辑行为,例如打日志、异步操作等。

  • Redux原生方法applyMiddlewares()
    它是 Redux 的原生方法,作用是将所有中间件组成一个数组,依次执行。源码实现原理是将入参的所有中间件被放进了一个数组chain,然后嵌套执行,最后执行store.dispatch

    bg2016092002.jpg

  • 异步中间件redux-thunkredux-promise

import { createStore, applyMiddleware } from 'redux';
import thunk from 'redux-thunk';
import reducer from './reducers';

// Note: this API requires redux@>=3.1.0
const store = createStore(
  reducer,
  applyMiddleware(thunk)
);

Redux参考

阮一峰:Redux 入门教程(一):基本用法
阮一峰:Redux 入门教程(二):中间件与异步操作
Redux入门教程(快速上手)
Redux教程

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

推荐阅读更多精彩内容