你可能需要Redux

前言

你可能并不需要Redux。
有点啪啪打脸的意思,但你必须权衡Redux架构给你项目带来的短期和长期的效益来决定是否应该使用Redux。如果只是一个简单的应用,Redux只会带来繁琐冗余的代码体验,这真的得不偿失。如果打算开发大型单页应用,Redux将会成为自然而然的选择。引用 Redux 的作者 Dan Abramov 的话说就是:

Flux 架构就像眼镜:您自会知道什么时候需要它。

Why Redux

当你在开发应用程序时,你一定会分解出很多组件进行开发,而各个组件之间想必在逻辑上多少是有关系的。那么组件之间的“通信”,就成了待解决问题。
通俗点说如果一个 model 的变化会引起另一个 model 变化,那么当 view 变化时,就可能引起对应 model 以及另一个 model 的变化,依次地,可能会引起另一个 view 的变化。直至你搞不清楚到底发生了什么。
以前我们试图用事件广播来避免这些连锁反应,但随之而来的问题是,在应用不断的扩展、变化中,广播事件也变得越来越复杂,越来越不可预料,以至于越来越难调试,越来越难追踪错误。
这当然不是我们想要的,我们希望应用的各个部分都易维护、可扩展、好调试、能预测。
于是Redux应运而生。

单向数据流


单向数据流可以说是Redux的设计核心。上图是一个表示“单向数据流”理念的极简示意。单向数据流要求各组件间的数据走向永远是单向的,可预期的。你不能直接改变 store 中的状态。改变 store 中的状态的唯一途径就是显式地提交Actions。这样使得我们可以方便地跟踪每一个状态的变化,从而让我们能够更好地了解我们的应用。

Action

Action是把数据从应用传到 store 的有效载荷。它是 store 数据的唯一来源。一般来说你会通过store.dispatch() 将 action 传到 store。你可以理解为这是一个修改数据的指令。
为什么要用Action?
store的数据操作封装在store内部,各组件禁止直接修改state数据,只能发布一个修改数据的意图通知store进行数据更新,这个意图就是Action。
按照约定,action 具有 type 字段来表示它的类型。type 可被定义为常量或者是从其它模块引入,最好使用字符串。除了 type 字段外,action 对象的结构完全取决于你。
为了使Action可复用,我们最好编写Action创建函数。

Reducer

Redux中的数据处理部分,我们称之为Reducer。
Reducer 就是一个纯函数,接收旧的 state 和 action,返回新的 state。
纯函数定义:相同的输入一定会对应相同的输出。翻译过来就是只要传入Action相同,返回计算得到的下一个 state 就一定相同。没有特殊情况、没有副作用,没有 API 请求、没有变量修改,单纯执行计算。
特别注意:不要修改 state。可以使用 Object.assign() 新建了一个副本或者借助Immutable.js。
Reducer过大时可以拆分Reducer。让每个 reducer 只负责管理全局 state 中它负责的一部分。每个 reducer 的 state 参数都不同,分别对应它管理的那部分 state 数据。

store

Redux 应用只有一个单一的 store。当需要拆分数据处理逻辑时,你应该使用 reducer 组合,而不是创建多个 store。
你可以通过createStore()接口创建你的store,第一个参数就是之前组合好的reducer,第二个参数用于设置 state 初始状态。第三个参数是一个高阶函数,主要用于Middleware。
store主要职责:

  • 提供 getState() 方法获取 state;
  • 提供 dispatch(action)方法更新 state;
  • 通过subscribe(listener) 注册监听器;

Middleware

Middleware提供的是位于 action 被发起之后,到达 reducer 之前的扩展点。 你可以利用 Middleware 来进行日志记录、创建崩溃报告、调用异步接口或者路由等等。
Redux middleware 就像一个链表。每个 middleware 方法既能调用 next(action) 传递 action 到下一个 middleware,也可以调用 dispatch(action) 重新开始处理,或者什么都不做而仅仅终止 action 的处理进程。
创建 store 时, applyMiddleware 方法的入参定义了 middleware 链,你只需要按照规定的格式编写你自己的Middleware即可。
applyMiddleware 实现原理其实很简单,代理store.dispatch,在调用前后插入自己的逻辑。

reducer enhancer

reducer enhancer作为一个函数,接收 reducer 作为参数并返回一个新的 reducer,这个新的 reducer 可以处理新的 action,或者维护更多的 state,亦或者将它无法处理的 action 委托给原始的 reducer 处理。
reducer enhancer可以看做是reducer的扩展,主要职责:

  • 统一修正reducer处理后的数据
  • 统一计算reducer处理后的计算属性
  • 实现撤销重做

Ending...

想要讲清楚Redux不是一件容易的事,文章也只是介绍了Redux的一些基本概念。
要想真正理清Redux,对应的项目经验是必不可少的。
如果你还在用low爆了的中介者模式或者难以管理的事件广播的话,强烈推荐迁移成Redux,你会发现一片不一样的天空。。。

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

推荐阅读更多精彩内容