深入浅出 React 和 Redux

内容简介

本书由浅入深地介绍如何用 React 和 Redux 构建现代化的前端项目,产出高质量的前端代码。共有12章。第1章介绍 React 应用开发的特点。第2章介绍开发高质量 React 组件的原则,详细介绍 React 组件的生命周期和数据管理方式。第3章由 Flux 引出 Redux框架,比较了不同框架的优劣。第4章开发了一个 Todo 应用,介绍将 React 和 Redux 结合的方法。第5章通过对 Todo 应用的性能优化,介绍提高 React 组件渲染性的方法。第6章介绍高阶组件和“以函数为子组件”的模式。第7章介绍如何在 React 和 Redux 的环境中实现和服务器通信。第8章介绍针对 React 和 Redux 的单元测试技巧。第9章介绍创建中间件和 StoreEnhancer 的技巧。第10章介绍在 React 中实现动画的技巧。第11章介绍如何创建多页面路由以及代码分片技巧。第12章介绍同构的概念和方法,使得 React 组件能够在服务器端和浏览器端进行渲染。

作者简介

程墨,资历架构师,曾任职于摩托罗拉、雅虎和微软,云鸟配送平台联合创始人,目前服务于美国视频服务公司 Hulu。

本书内容

前言

互联网技术发展一日千里,网页应用开发技术也不例外,这本书介绍的是在这一领域备受瞩目的两个工具 React 和 Redux。

自从 jQuery 问世以来,它就在网页开发领域占据统治地位,同时,还有许多 MVC 框架如雨后春笋般出现。但是业界也普遍发现,jQuery 和各种 MVC 框架在开发大型复杂应用时,依然面临很多难以克服的困难。

当2014年 Facebook 推出 React 时,给整个业界带来全新的看待网页应用开发的方式,和 React 一同问世的 Flux,也克服传统 MVC 框架的很多弊病。技术在不断发展,在2015年,Flux 的一个变体 Redux 出现,进一步优化了 Flux 的功能。

React 和 Redux 的结合,让网页开发的方式耳目一新,写这本书的初衷,是为了让国内读者能够一睹 React 和 Redux 的内在原理并深入实践。

在这里深入介绍 React 和 Redux,绝不是贬抑其他前端框架,事实上,开发者应该接触不同的开发模式,才能融会贯通,对技术有一个全面的认识,若要掌握某种技术,就要深入学习,这就是本书的目的。对 React 和 Redux 的了解不要只是停留在能用的表面功夫,重要的是理解内在的原理。

本书的内容

希望读者把阅读这本书的过程当做一个旅程,由浅入深地了解 React 和 Redux,如果你对 React 和 Redux 技术已经有一些了解,可以直接跳到感兴趣的章节。本书包括12章,如下所示。

第1章,React 新的前端思维方式。实际操作快速创建一个 React 应用,介绍和传统网页开发相比 React 应用开发的独特方式。

第2章,设计高质量的 React 组件。React 提倡基于组件的设计,这一章通过开发一个 ControlPanel 组件的实践,介绍了开发高质量 React 组件的原则,详细介绍 React 组件的生命周期和数据管理方式。

第3章,从 Flux 到 Redux。通过 Flux 介绍了单向数据流的框架模式,由此引出比 Flux 更优秀的 Redux 框架,通过用不同框架实现 ControlPanel 应用可以比较框架的优劣。

第4章,模块化 React 和 Redux 应用。这一章通过开发一个 Todo 应用介绍将 React 和 Redux 结合的方法。

第5章,React 组件的性能优化。通过对 Todo 应用的性能优化,介绍提高 React 组件渲染性的方法,以及提高从 Store 获取数据性能的方法。

第6章,React 高级组件。介绍高阶组件和“以函数为子组件”的模式。

第7章,Redux 和服务器通信。通过开发一个天气信息应用的实践,介绍应如何在 React 和 Redux 的环境中实现与服务器的通信。

第8章,单元测试。介绍针对 React 和 Redux 的单元测试技巧。

第9章,扩展 Redux。介绍创建中间件和 Store Enhancer 的技巧。

第10章,动画。介绍在 React 中通过 ReactTransitionGroup 和 React-Motion 库实现动画的技巧。

第11章,多页面应用。介绍如何创建多页面路由,以及为了提高网页装载性能的代码分片技巧。

第12章,同构。创建让 React 组件能够在服务器端和浏览器端渲染的技术。

本书的目标读者

阅读这本书只需要一些基本的 JavaScript、HTML 和 CSS 知识,了解网页应用的工作原理,就足够具备体验 React 和 Redux 这种全新的开发方式。

如果你熟悉传统的 jQuery 应用开发,那么通过阅读本书会让你发现不一样的应用构建模式;如果你之前学习过 Angular.js 或者 Vue.js,那么对理解 React 和 Redux 的工作机理很有帮助,同时有机会体验同样一种思想的不同实现之道。

即使你对 React 和 Redux 已经有了一定认识,相信阅读此书也不会让你觉得是浪费时间,因为书中不只是介绍“如何去做”,更多地还解释了“为什么这么做”,相信阅读此书会让你对 React 和 Redux 会有更多更深的认识。

源代码

本书每章都附带大量的实际代码例子,因为篇幅所限,在书中不可能包含所有代码,读者可以在 Github(网址https://github.com/mocheng/react-and-redux)上找到所有代码,代码按照所属章节内容组织。

如果读者发现代码或者书中的错误,可以直接在上面网址对应的代码库中提交问题,请不吝斧正。

致谢

首先要感谢我的家人,没有他们的帮助和理解,这本书不可能完成。

感谢 Hulu 公司,本书中的很多内容都是和 Hulu 的研发团队协同合作中得到的体会。

感谢机械工业出版社的吴怡编辑,因为她的鼓励和帮助,这本书才得以问世。

最后要感谢 React 和 Redux 社区,因为千千万万开发者以开放的心态贡献代码和积极讨论,前端开发技术才获得巨大的飞跃,这个世界才变得更加美好。

第1章 React 新的前端思维方式

/p>

      • 1.1 初始化一个 React 项目
        • 1.1.1 create-react-app 工具
      • 1.2 增加一个新的 React 组件
        • 1.2.1 JSX
        • 1.2.2 JSX 是进步还是倒退
      • 1.3 分解 React 应用
      • 1.4 React 的工作方式
        • 1.4.1 jQuery 如何工作
        • 1.4.2 React 的理念
        • 1.4.3 Virtual DOM
        • 1.4.4 React 工作方式的优点
      • 1.5 本章小结

我们先来直观认识 React,对任何一种工具,只有使用才能够熟练掌握,React 也不例外。通过对 React 快速入手,我们会解析 React 的工作原理,并通过与功能相同的 jQuery 程序对比,从而看出 React 的特点。

在这一章中,我们会介绍:

  • 如何初始化一个 React 项目;

  • 如何创建一个 React 组件;

  • React 的工作方式。

让我们开始旅程吧!

1.1 初始化一个 React 项目

为了开发 React 应用,你的电脑是运行微软 Windows 操作系统,还是苹果 Mac,或者是 Linux,并不重要,只需要保证具备以下条件:

  • 安装了浏览器,如果是 Windows 操作系统,请保证微软 IE 浏览器版本不低于8.0版,因为 React 不支持比 IE8 更低版本的浏览器;

  • 有一个命令行环境,在 Windows 操作系统中有命令行界面,在苹果 Mac 电脑中可以使用 Terminal 应用,对于 Linux 用户,命令行环境我想不用过多解释;

  • 一个你最喜欢的代码编辑器,用于编辑 React 应用的代码,本书内容注重实践,只有实际编码才能有深入体会。

作为开发者,推荐使用谷歌 Chrome 浏览器,因为 Chrome 浏览器自带的开发辅助工具非常友好,而且还可以安装辅助 React 和 Redux 的扩展工具,具体的开发工具在第4章4.2节中有详细介绍。

React 是一个 JavaScript 语言的工具库,在这个 JavaScript 工具铺天盖地的时代,没有意外,你需要安装 Node.js,React 本身并不依赖于 Node.js,但是我们开发中用到的诸多工具需要 Node.js 的支持。

在 Node.js 的官网(https://nodejs.org/)可以找到合适的安装方式,安装 Node.js 的同时也就安装了 npm,npm 是 Node.js 的安装包管理工具,因为我们不可能自己开发所有功能,会大量使用现有的安装包,就需要 npm 的帮助。

1.1.1 create-react-app 工具

React 技术依赖于一个很庞大的技术栈,比如,转译 JavaScript 代码需要使用 Babel,模块打包工具又要使用 Webpack,定制 build 过程需要 grunt 或者 gulp……这些技术栈都需要各自的配置文件,还没有开始写一行 React 相关代码,开发人员就已经被各种技术名词淹没。

针对这种情况,React 的创建者 Facebook 提供了一个快速开发 React 应用的工具,名叫 create-react-app,这个工具的目的是将开发人员从配置工作中解脱出来,无需过早关注这些技术栈细节,通过创建一个已经完成基本配置的应用,让开发者快速开始 React 应用的开发。

本书中所有应用实例都由 create-react-app 创建,我们用这种最简单的方式创建可运行的应用,必要的时候才会介绍底层技术栈的细节,毕竟,没有什么比一个能运行的应用更加增强开发者的信心。

create-react-app 是一个通过 npm 发布的安装包,在确认 Node.js 和 npm 安装好之后,命令行中执行下面的命令安装 create-react-app:

安装过程结束之后,你的电脑中就会有 create-react-app 这样一个可以执行的命令,这个命令会在当前目录下创建指定参数名的应用目录。

我们在命令行中执行下面的命令:

这个命令会在当前目录下创建一个名为 first_react_app 的目录,在这个目录中会自动添加一个应用的框架,随后我们只需要在这个框架的基础上修改文件就可以开发 React 应用,避免了大量的手工配置工作:

在 create-react-app 命令一大段文字输出之后,根据提示,输入下面的命令:

这个命令会启动一个开发模式的服务器,同时也会让你的浏览器自动打开了一个网页,指向本机地址 http://localhost3000/,显示界面如图1-1所示。

注意

本书中的截图是根据 create-react-app 1.0.0版本所得,其他版本产生的页面可能略有不同。

深入浅出 React 和 Redux

图1-2 ClickCounter 组件界面效果

去点击那个“Click Me”按钮,可以看到“Click Count”后面的数字会随之增加,每点击一次加一。

恭喜你,现在你已经构建了一个有交互性的组件!

现在让我们来逐步详细解释代码中各部分的要义。

在 index.js 文件中,使用 import 导入了 ClickCounter 组件,代替了之前的 App 组件。

import 是 ES6(EcmaScript6)语法中导入文件模块的方式,ES6 语法是一个大集合,大部分功能都被最新浏览器支持。不过这个 import 方法却不在广泛支持之列,这没有关系,ES6 语法的 JavaScript 代码会被 webpack 和 babel 转译成所有浏览器都支持的 ES5 语法,而这一切都无需开发人员做配置,create-react-app 已经替我们完成了这些工作。

在 ClickCounter.js 文件的第一行,我们从 react 库中引入了 React 和 Component,如下所示:

Component 作为所有组件的基类,提供了很多组件共有的功能,下面这行代码,使用的是 ES6 语法来创建一个叫 ClickCounter 的组件类,ClickCounter 的父类就是 Component:

在 React 出现之初,使用的是 React.createClass 方式来创造组件类,这种方法已经被废弃了,但是在互联网上依然存在大量的文章基于 React.createClass 来讲解 React,这些文章中依然有很多真知灼见的部分,但是读者要意识到,使用 React.createClass 是一种过时的方法。在本书中,我们只使用 ES6 的语法来构建组件类。

细心的读者会发现,虽然我们导入的 Component 类在 ClickCounter 组件定义中使用了,可是导入的 React 却没有被使用,难道在这里引入 React 没有必要吗/p>

事实上,引入 React 非常必要,你可以尝试删掉第一行中的 React,在网页中立刻会出现错误信息,如图1-3所示。

“http://lib.sinaapp.com/js/jquery/1.9.1/jquery-1.9.1.min.js”></script> <script src=“./clickCounter.js”></script> </body></html>

实际产品中,产生这样的 HTML 可以用 PHP、Java、Ruby on Rails 或者任何一种服务器端语言和框架来做,也可以在浏览器中用 Mustache、Hogan 这样的模板产生,这里我们只是把问题简化,直接书写 HTML。

jQuery 已经发展到 3.x 版,但已经不支持比较老的浏览器了,我们这里使用1.9.1的 jQuery 只是为了让这个网页在 IE8 上也能够运行。

上面的 HTML 只是展示样式,并没有任何交互功能,现在我们用 jQuery 来实现交互功能,和 jQuery 的传统一样,我们把 JavaScript 代码写在一个独立的文件 clickCounter.js 里面,如下所示:

用浏览器打开上面创造的 index.html,可以看到实际效果和我们写的 React 应用一模一样,但是对比这两段程序可以看出差异。

在 jQuery 的解决方案中,首先根据 CSS 规则找到 id 为 clickCount 的按钮,挂上一个匿名事件处理函数,在事件处理函数中,选中那个需要被修改的 DOM 元素,读取其中的文本值,加以修改,然后修改这个 DOM 元素。

选中一些 DOM 元素,然后对这些元素做一些操作,这是一种最容易理解的开发模式。jQuery 的发明人 John Resig 就是发现了网页应用开发者的这个编程模式,才创造出了 jQuery,其一问世就得到普遍认可,因为这种模式直观易懂。但是,对于庞大的项目,这种模式会造成代码结构复杂,难以维护,每个 jQuery 的使用者都会有这种体会。

1.4.2 React 的理念

与 jQuery 不同,用 React 开发应用是另一种体验,我们回顾一下,用 React 开发的 ClickCounter 组件并没有像 jQuery 那样做“选中一些 DOM 元素然后做一些事情”的动作。

打一个比方,React 是一个聪明的建筑工人,而 jQuery 是一个比较傻的建筑工人,开发者你就是一个建筑的设计师,如果是 jQuery 这个建筑工人为你工作,你不得不事无巨细地告诉 jQuery“如何去做”,要告诉他这面墙要拆掉重建,那面墙上要新开一个窗户,反之,如果是 React 这个建筑工人为你工作,你所要做的就是告诉这个工人“我想要什么样子”,只要把图纸递给 React 这个工人,他就会替你搞定一切,当然他不会把整个建筑拆掉重建,而是很聪明地把这次的图纸和上次的图纸做一个对比,发现不同之处,然后只去做适当的修改就完成任务了。

显而易见,React 的工作方式把开发者从繁琐的操作中解放出来,开发者只需要着重“我想要显示什么”,而不用操心“怎样去做”。

这种新的思维方式,对于一个简单的例子也要编写不少代码,感觉像是用高射炮打蚊子,但是对于一个大型的项目,这种方式编写的代码会更容易管理,因为整个 React 应用要做的就是渲染,开发者关注的是渲染成成什么样子,而不用关心如何实现增量渲染。

React 的理念,归结为一个公式,就像下面这样:

UI=render(data)

让我们来看看这个公式表达的含义,用户看到的界面(UI),应该是一个函数(在这里叫 render)的执行结果,只接受数据(data)作为参数。这个函数是一个纯函数,所谓纯函数,指的是没有任何副作用,输出完全依赖于输入的函数,两次函数调用如果输入相同,得到的结果也绝对相同。如此一来,最终的用户界面,在 render 函数确定的情况下完全取决于输入数据。

对于开发者来说,重要的是区分开哪些属于 data,哪些属于 render,想要更新用户界面,要做的就是更新 data,用户界面自然会做出响应,所以 React 实践的也是“响应式编程”(Reactive Programming)的思想,这也就是 React 为什么叫做 React 的原因。

1.4.3 Virtual DOM

既然 React 应用就是通过重复渲染来实现用户交互,你可能会有一个疑虑:这样的重复渲染会不会效率太低了呢竟,在 jQuery 的实现方式中,我们可以清楚地看到每次只有需要变化的那一个 DOM 元素被修改了;可是,在 React 的实现方式中,看起来每次 render 函数被调用,都要把整个组件重新绘制一次,这样看起来有点浪费。

事实并不是这样,React 利用 Virtual DOM,让每次渲染都只重新渲染最少的 DOM 元素。

要了解 Virtual DOM,就要先了解 DOM,DOM 是结构化文本的抽象表达形式,特定于 Web 环境中,这个结构化文本就是 HTML 文本,HTML 中的每个元素都对应 DOM 中某个节点,这样,因为 HTML 元素的逐级包含关系,DOM 节点自然就构成了一个树形结构,称为 DOM 树。

浏览器为了渲染 HTML 格式的网页,会先将 HTML 文本解析以构建 DOM 树,然后根据 DOM 树渲染出用户看到的界面,当要改变界面内容的时候,就去改变 DOM 树上的节点。

Web 前端开发关于性能优化有一个原则:尽量减少 DOM 操作。虽然 DOM 操作也只是一些简单的 JavaScript 语句,但是 DOM 操作会引起浏览器对网页进行重新布局,重新绘制,这就是一个比 JavaScript 语句执行慢很多的过程。

如果使用 mustache 或者 hogan 这样的模板工具,那就是生成 HTML 字符串塞到网页中,浏览器又要做一次解析产生新的 DOM 节点,然后替换 DOM 树上对应的子树部分,这个过程肯定效率不高。虽然 JSX 看起来很像是一个模板,但是最终会被 Babel 解析为一条条创建 React 组件或者 HTML 元素的语句,神奇之处在于,React 并不是通过这些语句直接构建 DOM 树,而是首先构建 Virtual DOM。

既然 DOM 树是对 HTML 的抽象,那 Virtual DOM 就是对 DOM 树的抽象。Virutal DOM 不会触及浏览器的部分,只是存在于 JavaScript 空间的树形结构,每次自上而下渲染 React 组件时,会对比这一次产生的 Virtual DOM 和上一次渲染的 Virtual DOM,对比就会发现差别,然后修改真正的 DOM 树时就只需要触及差别中的部分就行。

以 ClickCounter 为例,一开始点击计数为0,用户点击按钮让点击计数变成1,这一次重新渲染,React 通过 Virtual DOM 的对比发现其实只是 id 为 clickCount 的 span 元素中内容从0变成了1而已:

React 发现这次渲染要做的事情只是更换这个 span 元素的内容而已,其他 DOM 元素都不需要触及,于是执行类似下面的语句,就完成了任务:

React 对比 Virtual DOM 寻找差异的过程比较复杂,在第5章,我们会详细介绍对比的过程。

1.4.4 React 工作方式的优点

毫无疑问,jQuery 的方式直观易懂,对于初学者十分适用,但是当项目逐渐变得庞大时,用 jQuery 写出的代码往往互相纠缠,形成类似图1-4的状况,难以维护。

深入浅出 React 和 Redux

图1-5 React 的程序流程

React 等于强制所有组件都按照这种由数据驱动渲染的模式来工作,无论应用的规模多大,都能让程序处于可控范围内。

1.5 本章小结

在这一章里,我们用 create-react-app 创造了一个简单的 React 应用,在一开始,我们就按照组件的思想来开发应用,React 的主要理念之一就是基于组件来开发应用。

通过和同样功能的 jQuery 实现方式对比,我们了解了 React 的工作方式,React 利用声明式的语法,让开发者专注于描述用户界面“显示成什么样子”,而不是重复思考“如何去显示”,这样可以大大提高开发效率,也让代码更加容易管理。

虽然 React 是通过重复渲染来实现动态更新效果,但是借助 Virtual DOM 技术,实际上这个过程并不牵涉太多的 DOM 操作,所以渲染效率很高。

理解 React 的工作方式,是踏入 React 世界的关键一步,接下来我们详细介绍如何构建高质量的 React 组件。

第2章 设计高质量的 React 组件(上)
第2章 设计高质量的 React 组件(下)
第3章 从 Flux 到 Redux(上)
第3章 从 Flux 到 Redux(下)
第4章 模块化 React 和 Redux 应用(上)
第4章 模块化 React 和 Redux 应用(中)
第4章 模块化 React 和 Redux 应用(下)

来源:蔚1

声明:本站部分文章及图片转载于互联网,内容版权归原作者所有,如本站任何资料有侵权请您尽早请联系jinwei@zod.com.cn进行处理,非常感谢!

上一篇 2018年10月4日
下一篇 2018年10月4日

相关推荐