第1 章
Redux 介绍
本章涵盖:
● 定义Redux
● 了解Flux 与Redux 之间的差异
● 使用Redux 和React
● 介绍action、reducer 和store
● 学习何时使用Redux
在2018 年,如果你进入任何一个React Web 应用程序,很有可能就会发现是Redux
在管理其状态(state)。然而,能够如此之快地达到这个地步,是非常了不起的。几年前,
Redux 还尚未创建,而同期React 却拥有蓬勃发展的活跃用户群。React 的早期使用者
认为,他们已经找到视图层(view layer)——MVC(Model-View-Controller) 前端框架拼图
中的“V”——的最佳解决方案。尚未能达成共识的是,一旦应用程序的大小和复杂
度达到现实中所需的规模,应该如何管理它们的状态。最终,Redux 解决了这一争论。
在本书的整个讲解过程中,将会以一个React 应用程序为“镜头”,来探索Redux
及其生态系统。正如你将了解到的,可以将Redux 插入各种风格的JavaScript 应用程
序中,但是由于一些原因,React 是理想的练习场景。最主要的原因是,Redux 是在
React 的背景下创建的。你最有可能在React 应用程序中遇到Redux,而React 并不知道
如何管理应用程序的数据层。下面不再赘述,让我们开始吧!
1.1 什么是状态
React 组件具有本地状态(Local State ,又称组件状态)的概念。例如,在任何指定
的组件中,可以用于跟踪输入字段的值,或者跟踪按钮是否被单击过。本地状态可以
轻松管理单个组件的行为。然而,如今的单页面应用程序,通常需要同步复杂的状态
网。层级嵌套的组件,可以基于用户已经访问过的页面、AJAX 请求的状态或用户是
否已登录来呈现不同的用户体验。
让我们考虑一个涉及用户身份验证状态的用例。产品经理告诉你,当用户登录到
一个在线商店时,导航栏应该显示用户的头像,该在线商店应首先展示离用户地址最
近的商品,并且应该隐藏新闻邮件注册表单。在普通的React 架构中,能做的仅限于
在每个组件之间同步状态。最后,很可能会将用户身份验证状态和其他用户数据从一
个顶级组件向下传递到每个嵌套组件。
这种架构存在几个缺点。在该过程中,数据可能在不需要它的组件间过滤,而非
将其传递给组件的子级。在大型应用程序中,这可能会导致不相关的组件之间出现大
量的数据移动,通过props 向下传,或通过回调向上传。很可能,位于应用程序顶层
的少数组件,最终会知道整个应用程序中用到的大多数状态。当达到一定规模后,维
护和测试代码会变得难以为继。由于React 并非旨在像其他MVC 框架一样解决同样
广泛的问题,因此,就存在弥合这些差别的机会。
考虑到React,Facebook 最终推出了Flux,这是一种用于Web 应用程序的架构模
式。Flux 在前端开发领域变得极具影响力,并开始转变人们对客户端应用程序中状态
管理的看法。对于这种模式,Facebook提供了自己的实现,但很快就出现十多个受Flux
启发的状态管理库,争夺着React 开发人员的注意力。
对于希望扩展应用程序的React 开发人员,这是个混乱的时期。尽管已经看到Flux
的亮点,但也应继续尝试,以寻找更优雅的方式来管理应用程序中复杂的状态。有段
时间,新人遭遇了选择悖论,分裂的社区力量产生了如此多的选项,这诱发了焦虑。
不过,令人惊讶和欣喜的是,一切已尘埃落定,Redux 成为其中明显的胜出者。
Redux 通过一个简单的前提,一份巨大的回报,以及一次令人难忘的介绍,彻底
征服了React 世界。这个前提是,使用纯函数将整个应用程序的状态存储在一个单独
的对象中。这份回报则是,应用程序的状态将会是完全可预见的。对大多数早期用户
而言,有关Redux 的介绍来自于丹·阿布拉莫夫(Dan Abramov)在2015 年React 欧洲
会议上的演讲,标题为Live React:Hot Reloading with Time Travel (演讲视频可参考
https://www.youtube.com/watch?v=xsSnOQynTHs) 。Dan 展示了打破已有工作流程的
Redux 开发经验,令与会者赞叹不已。一种称为热加载(hot loading)的技术,可在保持已
有状态的同时让应用程序实时更新,并且新的Redux 开发者工具能够在应用程序状
态间进行时间旅行——只需要单击一下,就能倒回并重放用户操作。这种综合效果为
开发人员提供了强大的调试能力,在第3 章中将会详细介绍。
为了理解Redux,首先要适当介绍一下Flux,它是由Jing Chen 为Facebook 开发
的一种架构模式(关于Jing Chen,详见https://facebook.github.io/flux/docs/ videos.html)。
Redux 及其许多替代方案都是Flux 架构的变体。
1.2 什么是Flux
最重要的一点在于Flux 是一种架构模式。它是作为主流的JavaScript MVC 模式
的替代品被开发的,JavaScript MVC 模式因现存框架(例如Backbone、Angular 或Ember)
的流行而普及。尽管每个框架对MVC 模式都有自己的实现,但许多框架都有类似的
问题:通常,模型(model)、视图(view)和控制器(controller)之间的数据流可能会难以理
解追寻。
许多这类框架使用双向数据绑定(two-way data binding),其中视图的改变会更新
相应的模型,并且模型中的更改会更新相应的视图。当任何给定的视图能够更新一个
或多个模型,而这个或这些模型又可以更新更多的视图时,就会无法很好把握预期的
结果,某种程度上这也无可指责。Chen 争辩说,尽管MVC 框架适用于较小的应用程
序,但这些框架所采用的双向数据绑定模型的扩展性,不足以满足Facebook 的应用
程序规模。由于害怕杂乱的依赖网会产生意想不到的后果,Facebook 的开发人员对做
出的更改变得担心。
Flux试图解决状态的不可预知性,以及模型与视图紧密耦合的架构的脆弱性。Chen
废弃了双向数据绑定模型,转而采用单向数据流。Flux 要求对状态的所有修改遵循单
一的路径,而不允许每个视图(view)与对应的模型进行交互。例如,当用户单击表单
中的Submit 按钮时,会向应用程序的唯一dispatcher(调度程序)发送一个操作(action)。
然后,该dispatcher 将数据发送到合适的数据存储进行更新。一旦更新后,视图将会
知道要渲染的新数据。图1.1 对这种单向数据流进行了说明。
图1.1 Flux 指定数据必须单向流动
1.2.1 action
状态的每一次改变都始于一个action(参见图1.1),action 是描述应用程序事件
的JavaScript 对象。它们通常由用户交互或服务器事件(例如HTTP 响应)产生。
1.2.2 dispatcher
Flux 应用程序中的所有数据流都通过单一的dispatcher 进行汇集。dispatcher 自身
的功能很少,因为其目的是接收所有的action,并将它们发送到已注册的每个store。
每个action 会被送到每个store。
1.2.3 store
每个store 管理应用程序中一个域的状态。例如,在电子商务网站中,可能会找到
一个购物车store 和一个产品store。一旦把一个store 注册到dispatcher,它就开始接
收action。当store 接收到它关心的action 类型时,它就会进行相应的更新。一旦store
产生更改,就会广播一个事件,让视图使用新的状态进行更新。
1.2.4 视图
Flux 可能在设计时考虑了React,但视图并不需要React 组件。对视图而言,它们
只需要订阅要显示的数据的store。Flux 文档鼓励使用“控制器-视图”模式,借助一
个顶级组件处理与store的通信,并将数据传递给子组件。让一个父组件和一个嵌套的
子组件通过store 通信,可能导致额外的渲染以及意想不到的副作用。
重申,Flux 首先是一种架构模式。Facebook 团队维护了这种模式的一个简单的实
现方案,恰当地(或令人困惑地,取决于如何看待)命名为Flux。自2014 年以来,已出
现许多替代实现方案,包括Alt、Reflux 和Redux。有关这些替代实现方案的更全面
的列表请参见1.6 节。
1.3 什么是Redux
最好的解答来自官方文档:“Redux 是JavaScript 应用程序的可预测状态的容器”
(https://redux.js.org/) 。Redux是一个独立的库,但最常用作React 的状态管理层。与Flux
一样,其主要目标是为应用程序中的数据带来一致性和可预测性。Redux 将状态管理
职责划分成以下几个独立的单元:
● store将应用程序的所有状态都存储在单个对象中(通常将此对象称为对象树)。
● 只能使用action 更新store,action 是描述事件的对象。
● 被称作reducer 的函数指定了如何转换应用程序的状态。reducer是函数,它接
收store 中的当前状态和一个action,然后返回更新后的下一个状态。
从技术上讲,Redux 可能不符合Flux 的实现。它与Flux 架构规定的若干构件有
明显偏离,例如,完全移除了dispatcher。最终,Redux 是类Flux 的架构,而区别在
于语义问题。
Redux 得益于源自Flux 架构的可预测数据流,但它也找到了方法以降低store 回
调注册的不确定性。正如前面提到的,要调和多个Flux store 的状态可能会很痛苦。
相反,Redux 规定了一个单一的store 来管理整个应用程序的状态。关于Redux 的工
作原理和相关的更多内容,后续章节将会有更多的介绍。
1.3.1 React 和 Redux
尽管Redux 是基于React 设计并开发的,但这两个库是完全解耦的。如图1.2 所
示,React 和Redux 使用绑定进行连接。
图1.2 Redux 不是任何现有框架或库的一部分,但称为绑定的附带工具将Redux 和React 连接了起来,
本书将使用react-redux 包
事实证明,Redux的状态管理范式可以与大多数JavaScript框架一起实施。Angular、
Backbone、Ember及很多技术都支持绑定。
虽然本书基本上是关于Redux 的,但也会将Redux 与React 紧密联系。尽管Redux
是一个独立的小型库,但它与React 组件非常吻合。Redux 有助于定义应用程序做什
么,而React 将处理应用程序的外观。
本书将会编写的大部分代码,以及阅读期间要编写的React/Redux 代码,将分为
以下几类:
● 应用程序的状态和行为,由Redux 处理。
● 绑定——由react-redux 包提供——用于连接Redux store中的数据和视图(React
组件)。
● 包含大部分视图层的无状态组件。
你将会发现,React 是Redux 天然的生态系统。React 为Redux 引入并管理更大
的应用程序状态敞开大门,同时React 具有在组件内部直接管理状态的机制。如果
对其余的生态系统感兴趣,第12 章将探讨Redux 与其他几个JavaScript 框架之间的
关系。
1.3.2 3 个原则
Redux 中的状态由单一的可信数据源(single source of truth)表示,是只读的,并且
只能用纯函数进行修改。领会了这些也就有了坚实的基础。
单一数据源
与Flux 架构规定的各种域的store 不同,Redux 在store 内部的对象中管理整个应
用程序的状态。使用单一的store 具有重要的意义,可以在单个对象中表示整个应用
程序状态的能力,简化了开发人员的体验。通过思考应用程序流程,预测新操作的结
果以及调试任何给定的action 产生的问题,都会非常容易。时间旅行调试(time-travel
debugging)的潜力,或在应用程序状态快照中来回穿梭的能力,正是发明Redux 的首
要动力。
状态是只读的
与Flux 一样,action 是应用程序状态发起改变的唯一方式。在不通过action 进行
通信的情况下,零散的AJAX 调用不能引起状态的改变。Redux 与许多Flux 实现的不
同,在于action 不会导致store 中的数据突变。相反,每个action 都会产生一个崭新的
状态实例来替换当前状态。
改变由纯函数进行
通过reducer 接收action。重要的是,这些reducer 是纯函数。纯函数是确定的,
在给定相同输入的情况下,它们总是产生同样的结果,并且过程中不会改变任何数据。
如果reducer 在生成新状态的同时改变现有的状态,则最终可能出现错误的新状态,
也会丢失每个新action 应该提供的可预测的事务日志。Redux 开发者工具,以及诸如
撤销和重做等其他特性,依赖于由纯函数计算所得的应用程序状态。
1.3.2 工作流
前面已经简要提到过action、reducer 及store 等主题,但本节将对每个主题做更
深入的介绍。在此重点介绍每个元素扮演的角色,以及它们如何协同工作以产生期望
的结果。现在,不必担心更精细的实现详情,因为后续章节中会有足够的时间来运用
将要探索的概念。
现代的Web 应用程序最终是与处理事件相关的。事件可以由用户发起,例如导航
到新页面或提交表单。也可以由另外的外部源发起,例如服务器响应。响应事件通常
涉及更新状态并使用更新后的状态重新渲染。应用程序处理事件越多,需要追踪并更
新的状态就越多。将这种情况和大部分这些事件都是异步发生的事实相结合,突然就
会遭遇维护大规模应用程序的真正障碍。
Redux 的职责是,创建应用程序中有关如何处理事件以及管理状态的结构。希望
在此过程中人们更加高效、快乐。
来看看如何使用Redux 和React 在应用程序中处理单个事件。假设任务是实现社
交网络的核心功能之一——添加一个帖子到活动流(activity feed)。图1.3 展示了用户
资料页面的一个快速模型,灵感可能是也可能不是源自Twitter 。
图1.3 用户资料页面的一个快速模型。该页面由两个主要的数据支持:帖子总数和用户
活动流中的帖子对象列表
处理诸如发布新帖之类的事件涉及以下不同步骤:
(1) 从视图中,指示事件已发生(帖子提交)并传递必要的数据(要创建的帖子的
内容)。
(2) 根据事件的类型更新状态,在用户活动流中添加一项并增加帖子数。
(3) 重新渲染视图以反映更新后的状态。
听起来很合理吧?如果以前使用过React,可能就直接在组件中实现了与此类似
的功能。Redux 采用不同的方法,用于完成这3 项任务的代码从React 组件被移到了
几个单独的实体中。尽管已经熟悉图1.4 中的视图,但我们还是会兴奋地引入一组新
的角色,希望你能够学习掌握。
图1.4 看看数据如何在React/Redux 应用程序中流动,我们省略了一些常见部分,如中间件和选择器,
这些内容将在后续章节中深入介绍
action
为响应用户提交新帖要做两件事:将帖子添加到用户活动流并增加总的帖子数。
在用户提交之后,将通过派发一个action 来启动该过程。action 是表示应用程序中事
件的JavaScript 对象字面量,如下所示:
{
type: 'CREATE_POST',
payload: {
body: 'All that is gold does not glitter'
}
}
拆解来看,action 是一个具有以下两个属性的对象:
● type——表示正在执行的action 类别的字符串。根据惯例,type 属性的值大写,
并使用下划线作为分隔符。
● payload——提供执行action 所需数据的一个对象。本例中,只需要一个字段:
想要发布的消息的内容。名称“payload”(有效载荷)仅是一种流行的惯例。
action 具有作为审计的优势,它保留了应用程序中发生的所有事件的历史记录,
包括完成事务所需的任何数据。在保持对复杂应用程序的掌控方面,其价值不可低估。
一旦习惯使用具有高度可读性的流来实时描述应用程序的行为,就会发现没有了它便
很困难。
在整本书中,将会经常回顾这个理念。可以将Redux 视为对应用程序中发生了什
么以及如何响应事件的解耦。action 处理发生了什么。action 描述一个事件,它不知
道也不关心下游会发生什么。最终,沿途的某处需要指定如何处理action。这听上去
像是适合reducer 完成的任务!
reducer
reducer 是负责更新状态以响应action 的函数。它们是简单的函数,接收当前状态
和一个action 作为参数,并返回下一个状态,如图1.5 所示。
图1.5 reducer 函数签名的抽象表示。这个图解看起来很简单,那是因为它本来就简单。
reducer 是用于计算结果的简单函数,它们易于使用和测试
reducer 通常易于使用。与所有的纯函数类似,它们不会产生副作用。它们不会以
任何方式影响外部,并且是引用透明的。相同的输入将始终产生相同的返回值。这使
它们特别容易测试,给定特定输入,就可以验证是否会收到预期的结果。图1.6 显示
了reducer 如何更新帖子列表和总帖子数。
图1.6 努力想象一个工作中的reducer。它接收一个action 和当前状态作为输入。reducer 的唯一职责是
根据这些参数计算下一个状态。没有突变,没有副作用,没有业务逻辑。输入数据,输出数据
这个例子中关注的是单个事件,这意味着只需要一个reducer。然而,肯定不仅限
于(使用)一个。实际上,更大的应用程序通常实现若干个reducer,每一个都会关注状
态树的不同切片。这些reducer 会被联合或组合成“根reducer”(root reducer)。
store
reducer 描述了如何更新状态以响应action,但它们无法直接修改状态。这种特权
仅限于store 拥有。
在Redux 中,应用程序状态存储在单个对象中。store 拥有以下几个主要角色,其
中包括:
● 持有应用程序状态。
● 提供一种访问状态的方式。
● 提供一种方式来指定对状态的更新。store 要求派发一个action 来修改状态。
● 允许其他实体订阅更新(React 组件属于这种情况)。通过react-redux 提供的视
图绑定可以接收来自store 的更新,并在组件中对其做出响应。
reducer 处理action 并计算下一个状态。然后轮到store 更新自身,并将新状态广
播给所有已注册的监听者(请特别关注组成个人资料页面的组件),参见图1.7。
熟悉了最重要的几个构件后,我们来看一张更全面的Redux 架构图。虽然其中几
块现在还不熟悉,但在本书中将会反复提到此图(参见图1.8),而随着时间的推移,每
个空白都会被填补。
回顾此图,与视图的交互可能会引发一个action。该action 将通过一个或多个
reducer 进行过滤,并在store 中生成新的状态树。一旦状态更新,视图将意识到有
新的数据要渲染。这就是整个循环!图1.8 中带有虚线边框的条目(action创建器、中
间件和选择器)是Redux 架构中可选但又强大的工具。后续章节中会介绍这些主题。
图1.7 通过向个人资料页面提供新的状态,store 完成了循环。请注意,帖子数已增加,并且新
帖子已被添加到活动流。如果用户想要添加其他帖子,将遵循与此相同的流程。视图派发
action,reducer 指定如何更新状态,store 会把新状态广播返回给视图
图1.8 当继续前进时,此图将锚定你对Redux 元素的理解。目前,已经讨论了
action 、reducer 、store 和视图
如果感觉这些内容太多了,请不要烦恼。正要探索的这种单向架构,对于新手,
起初可能会不知所措(我们最初也这么认为)。领会这些概念需要一些时间。它们扮演
什么角色,以及什么类型的代码属于哪里,要对此养成意识,既像是艺术也像是科学。
随着不断的练习,你将会掌握这种技能。
1.4 为什么要用Redux
到目前为止,你已经触及Redux 的许多要点。在完成第1 章时,如果必须向老板
推销Redux,那么可以将这些理念整合到一个精彩的片段中。简而言之,Redux 是一个
小型且易于学习的状态管理库,可以生成高度可预测、可测试并可调试的应用程序。
1.4.1 可预测性
Redux 的最大卖点是,它为处理应用程序的复杂状态带来了条理性。Redux 架构
提供了一种直观的方式来概念化并管理状态,一次一个action。无论应用程序的大小
如何,单向数据流内的action 会让针对单一store 的更改是可预测的。
1.4.2 开发者体验
可预测性使出现世界一流的调试工具成为可能。热加载(hot-loading)和时间旅行
(time-travel)调试工具为开发人员提供了更快的开发周期,无论是构建新功能还是寻找
bug。老板喜欢开心的开发人员,但更喜欢开发效率高的开发人员。
1.4.3 可测试性
需要编写的Redux 实现代码主要是函数,其中许多都是纯函数。每一块都可以轻
松分解并隔离进行单元测试。官方文档使用Jest 和Enzyme,但无论喜欢哪个JavaScript
测试库,都可以完成测试。
1.4.4 学习曲线
Redux 是原生React 的自然进阶,体积非常小,只公开了少量API 用于完成工作。
一天之内就可以熟悉Redux 的所有内容。编写Redux 代码还需要团队熟悉几种函数式
编程范式。对于某些开发人员来说,这将是一个新的领域,但相关概念是清晰易懂的。
一旦理解对于状态的更改只能由纯函数产生,就已经掌握了大部分内容。
1.4.5 体积
如果老板正在工作,那么检查清单中的重要一项就是项目依赖的大小。Redux 是
个微型库——压缩后小于7KB 。胜出!
1.5 何时应该使用Redux
虽然关于Redux 如何出色已经介绍了很多,但Redux 并非万能灵药。虽然讨论了
为什么应该使用Redux,但众所周知,天下没有免费的午餐,也不存在无须权衡折中
的软件模式。
使用Redux 的代价是会产生很多的模板代码,以及相比React 本地组件状态更高
的复杂度。重要的是要意识到:对于团队中的新开发人员来说,在他们能做出贡献之
前,还需要学习Redux 及其使用模式。
Redux 的联合创始人Dan Abramov 在这一点上也有权衡考虑,甚至发表了一篇名
为“ 你可能不需要Redux ” (You Might Not Need Redux) 的博文( 博客地址为
https://medium.com/@dan_abramov/you-might-not-need-redux-be46360cf367) 。他建议开
始时不使用Redux,仅在遭遇足够多的状态管理痛点,能证明包含Redux 是合理的之
后才引入Redux。该建议刻意描述得模糊不清,因为每个团队的转折点会略有不同。
没有复杂数据需求的较小应用程序是最常见的情况,这种情况下不使用Redux 而使用
普通的React 可能会更加合适。
那些痛点可能是什么样的呢?团队可以使用一些常见的场景来证明引入Redux
的合理性。第一种场景是,在几层不会使用任何数据的组件间传递数据。第二种场景
是,处理在应用程序的不相关的部分之间共享和同步数据。对于使用React 实现这些
任务,我们都有一定容忍度,但最终会有容忍极限。
如果知道自己想要构建的特定功能是Redux 擅长的,Redux 很可能会是不错的选
择。如果知道应用程序会有复杂的状态,并且需要撤销与重做功能,请直截了当地引
入Redux。如果需要服务端渲染,请优先考虑Redux。
1.6 Redux 的备选方案
如前所述,Redux 进入了拥挤的状态管理市场,而此后也出现了更多的可选方案。
来看一下用于React 应用程序状态管理的最流行的替代方案。
1.6.1 Flux 的一些实现
在研究时,我们数了数,有20 多个Flux 实现的库。令人惊讶的是,至少其中有8 个
已经在GitHub 上收到超过1000 个星星。这突显了React 历史上的一个重要时代——Flux
是一种开创性理念,激发了社区的活力,并因此推动大量的试验与发展。在此期间,
代码库以令人应接不暇的速度来来去去,这也造就了“JavaScript 疲劳”(JavaScript
Fatigue)一词。事后来看,很明显,这些试验中的每一个都是途中重要的垫脚石。随着
时间的推移,许多备选的Flux 实现的维护者优雅地退出了比赛,转而支持Redux 或
其他一些流行的方案中的某个,但是仍然有几个维护良好的备选方案。
Flux
Flux 当然是这一切的开始。用维护者自己的话说,“Flux 更像一种模式而非框架”。
在这个代码库中,能找到大量有关Flux 架构模式的文档,但对于方便地使用Flux 构
建应用程序,只暴露了少量的API。dispatcher 是Flux 的核心,事实上,其他几个Flux
实现已将dispatcher 整合到它们的库里。按GitHub 上的星星个数来衡量,Flux 的流行
度大概是Redux 的一半,而且继续由Facebook 团队积极维护。
Reflux
Reflux 是原始的Flux 的快速跟随者。Reflux 将函数响应式编程(functional reactive
programming)思想引入Flux 架构中,剥离了单个的dispatcher,进而让每个action 都
具有派发自身的能力。回调函数可以和更新store 的action 一起注册。Reflux 仍在维
护,并且以GitHub 上的星星个数衡量,它的流行度大概有Redux 的六分之一。
Alt
与Reflux 不同,Alt 符合原始的Flux 理念并使用Flux dispatcher。Alt 的卖点在于
它对Flux 架构的坚持并减少了模板代码。Alt 曾经拥有一个活跃的社区,但在撰写本
书时,已经有6 个月没有提交记录了。
荣誉榜单
在GitHub 上超过1000 个星星的(Flux 实现)库中,还有Fluxible、Fluxxor、NuclearJS
以及Flummox。Fluxible 继续由Yahoo 团队维护。Fluxxor、NuclearJS 及Flummox 可
能还在维护,但不再活跃。强调这些项目是因为它们是重要的垫脚石,Flummox 是由
Andrew Clark 创建的,Andrew Clark 后来与Dan Abramov 一起创建了Redux。
1.6.2 MobX
MobX 为状态管理提供了一种函数响应式解决方案。与Flux 类似,MobX 使用
action 修改状态,但组件会对变化后的或可观察的状态做出响应。虽然函数响应式编
程中的部分术语令人生畏,但在实践中这些概念易于理解和接受。MobX 需要的模板
代码相比Redux 更少,但在底层做了很多事情,因此更含蓄。在2015 年年初,MobX
的第一次提交仅比Redux 早几个月。
1.6.3 GraphQL 客户端
GraphQL 是一项激动人心的新技术,也是由Facebook 团队开发的。它是一种查
询语言,允许准确指定并接收组件所需的数据,非常适合React 组件预期的模块化,
组件所需的任何数据的获取都封装在其中。API 的查询针对父子组件的数据需求进行
了优化。
通常,GraphQL 与GraphQL 客户端一起使用。如今最受欢迎的两个客户端是Relay
和Apollo。Relay 是由Facebook 团队(和开源社区)开发维护的另一个项目。起初,Apollo
的底层是使用Redux 实现的,但现在提供了额外的可配置性。
虽然可以同时引入Redux 和GraphQL 客户端来管理同样的应用程序状态,但你
会发现该组合可能过于复杂且不必要。虽然GraphQL 处理数据从服务器的获取,而
Redux 更通用一些,但它们的用途有重叠之处。
1.7 本章小结
本章介绍了Flux 架构模式以及Redux 的运行,你了解了有关Redux 的一些实
际细节。
现在,你已经准备好将基本的构件放在一起,并端到端地查看运行中的Redux 应
用程序。在下一章中,将使用Redux 和React 构建一个任务管理应用程序。
本章的学习要点如下:
● Redux 的状态存储在单个对象中,并且是纯函数的产物。
● Redux可以引入可预测性、可测试性以及复杂应用程序的可调试性。
● 如果经历过在应用程序中同步状态或在多层级组件间传递数据的痛点,请考
虑引入Redux。
节选自《Redux 实战》第一章
《Redux 实战》试读电子书,免费提供,有需要的留下邮箱,一有空即发送给大家。邮箱留到微信回复更快(邮箱地址+试读书名),别忘啦顶哦!
微信:qinghuashuyou
更多最新图书请点击查看哦(即日起:关注@qinghuashuyou 发送:关注技术方向,不定时有新书上新,参与互动即有机会获得推广新书样书)