React快速上手开发(txt+pdf+epub+mobi电子书下载)


发布时间:2020-06-30 09:34:29

点击下载

作者:斯托扬·斯特凡诺夫 (Stoyan Stefanov)

出版社:人民邮电出版社

格式: AZW3, DOCX, EPUB, MOBI, PDF, TXT

React快速上手开发

React快速上手开发试读:

前言

大约 2000 年,洛杉矶。这又是一个温暖舒适的加利福尼亚之夜,淡淡的海风轻轻拂来,舒爽惬意。我正准备使用 FTP 把我新建的站点 CSSsprites.com 传送到服务器并向全世界发布。在发布的前几个晚上,我一直在思考一个问题:“到底为什么只把 20% 的工作量放在解决应用的主要问题上,却把剩下的 80% 花费在努力克服用户界面的问题上呢?”如果能把所有调用 getElementById() 和考虑应用状态(用户上传是否完成?如果上传出错,上传对话框是否要继续显示?)的时间节约出来,我能利用这部分时间完成多少其他的工具呢?为什么界面开发这么耗时?如何处理不同浏览器之间的差异?想到这些,我的大好心情荡然无存。

时间快进到 2015 年 3 月。在当时召开的 Facebook F8 开发者大会上,我所在的团队准备公布两个完全重写的 Web 应用:一个第三方评论模块和一个配套的评论审核工具。和我的小应用 CSSsprites.com 相比,这两个应用非常成熟,功能也复杂得多,并且流量非常大。虽然如此,其开发过程依然令人愉悦。团队中的新成员(甚至包括刚接触 JavaScript 和 CSS 的新手)都能很快地融入其中,轻松高效地贡献功能特性并改进现有代码。团队中的一个成员说:“现在我发现这就是自己热爱的一切!”

在这段时间里发生了什么?答案是:React 诞生了。

React 是一个 UI 库,让你只需定义一次用户界面,就可以将其用在多个地方。之后,当应用的状态(state)发生变化时,React 将会自动作出反应、更新界面,你无需做其他任何工作。毕竟你已经定义了用户界面。尽管说是定义,其实代码更加偏向声明式,你可以使用可管理的小型组件构造出一个强大的应用。你再也不需要在函数里花费一半的代码量寻找 DOM 节点了,而是可以只维护应用的状态(通过常规的 JavaScript 对象),把剩下的工作都交给 React 帮你完成。

学习 React 非常划算。一旦学会这个库,便可以使用它构建以下类型的应用:

Web 应用

原生 iOS 和 Android 应用

Canvas 应用

TV 应用

原生桌面应用

你可以使用与构造组件和用户界面相同的思路,创建具有原生应用性能和控制能力的原生应用(真正的原生控制,而不仅仅是看起来像原生)。这并不是指“一次编写,到处运行”(我们的技术尚未实现这一点),而是“一次学习,到处使用”。

简而言之,学习 React 可以帮你节省 80% 的时间,使你可以把精力集中在主要问题上(比如你的应用存在的真正目的)。关于本书

本书从 Web 开发的角度介绍如何学习 React。在前 3 章,你将从一个空白的 HTML 页面开始构建应用。这使得你可以将关注点放在 React 本身,无需了解任何新语法或者辅助工具。

第 4 章介绍 JSX。这是一项单独、可选的技术,通常会同 React 一起使用。

从第 5 章开始,你将学习在实际开发中可能用到的一些附加工具。介绍的例子包括 JavaScript 打包工具(Browserify)、单元测试(Jest)、语法检查(ESLint)、类型(Flow)、在应用中组织数据流(Flux)以及不可变数据(Immutable.js)。所有关于这些辅助技术的讨论都会力求简化,让你依然将精力放在 React 上。你会很快熟悉这些工具的使用,并能根据具体情况选择使用哪些工具。

祝你在学习 React 的过程中一切顺利,大有收获!该图标表示一般说明。该图标表示提示或建议。该图标表示警告或提醒。®Safari 在线图书

Safari Books Online(http://www.safaribooksonline.com)是应运而生的数字图书馆。它同时以图书和视频的形式出版世界顶级技术和商务作家的专业作品。技术专家、软件开发人员、Web 设计师、商务人士和创意专家等,在开展调研、解决问题、学习和认证培训时,都将 Safari Books Online 视作获取资料的首选渠道。

对于组织团体、政府机构和个人,Safari Books Online 提供各种产品组合和灵活的定价策略。用户可通过一个功能完备的数据库检索系统访问 O'Reilly Media、Prentice Hall Professional、Addison-Wesley Professional、Microsoft Press、Sams、Que、Peachpit Press、Focal Press、Cisco Press、John Wiley & Sons、Syngress、Morgan Kaufmann、IBM Redbooks、Packt、Adobe Press、FT Press、Apress、Manning、New Riders、McGraw-Hill、Jones & Bartlett、Course Technology 以及其他几十家出版社的上千种图书、培训视频和正式出版之前的书稿。要了解 Safari Books Online 的更多信息,我们网上见。致谢

感谢在本书组稿的不同阶段阅读本书并给我发送反馈和修正意见的所有人:Andreea Manole、Iliyan Peychev、Kostadin Ilov、Mark Duppenthaler、Stephan Alber 和 Asen Bozhilov。

感谢 Facebook 每天开发或者使用 React 以及回答我问题的所有同事。此外还要感谢为 React 提供工具和库以及撰写文章和使用说明的 React 开发者社区。

非常感谢 Jordan Walke。

感谢 O'Reilly 的所有人,本书的出版离不开你们的努力:Meg Foley、Kim Cofer、Nicole Shelby 等。

感谢 Yavor Vatchkov 为本书中的示例应用设计了用户界面(可以在 whinepad.com 体验)。  第1章 Hello World

让我们踏上使用 React 开发应用的旅程吧。在这一章里,你将学习如何设置 React 并编写你的第一个 Hello World 应用。1.1 设置

首先需要获取一份 React 库的源代码。所幸的是,这个过程非常简单。

访问 http://reactjs.com(这个网站会重定向到 React 的官方 GitHub 页面,即 http://facebook.github.io/react/),然后点击 Download 按钮,再点击 Download Starter Kit,即可获得一份 ZIP 文件。解压该文件,并把压缩包中的目录复制到一个方便找到的地方。

例如:mkdir ~/reactbook mv ~/Downloads/react-0.14.7/ ~/reactbook/react

现在你的工作目录(reactbook)应该如图 1-1 所示。图 1-1:你的 React 目录列表

现在,我们只使用其中的 ~/reactbook/react/build/react.js 文件。我们会在后续的学习中逐步介绍其他文件的使用。

需要注意的是,React 并没有强制规定任何目录结构。因此,你可以根据具体情况把 React 移动到其他目录,或者对 react.js 文件进行重命名操作。1.2 Hello React World

我们首先在工作目录中编写一个简单的页面(~/reactbook/01.01.hello.html): Hello React

该文件仅有两个值得我们注意的地方:引入了 React 库及其 DOM 插件库(通过

尽管方法奏效,性能也不错,但是它仍有一些缺点。

监听器的声明代码远离视图组件,使得代码难以搜索与调试。

使用委托总要经过 switch 结构,在你开始进行实际逻辑编写之前,需要创建不必要的样板代码。

实际中为处理浏览器的不一致性(上述代码中省略了这一步骤),会让代码变得更加冗长。

不幸的是,在你打算把这段代码放到真实环境给用户使用之前,还需要做更多工作,以支持所有主流浏览器。

除了 addEventListener 之外还需要 attachEvent。

要在监听器顶部使用 event = event || window.event;。

需要使用 var button = event.target || event.srcElement;。

尽管以上所有都是必需的,但是非常令人厌烦,因此你最终可能会选用某种类型的事件库作为代替。然而,React 自带一套解决方案来帮助你摆脱事件处理的噩梦,为什么还要添加另一个库(并学习更多的 API)呢?2.6.2 React 的事件处理

为了包裹并规范浏览器事件,React 使用了合成事件来消除浏览器之间的不一致情况。有了 React 的帮助,现在你可以依靠 event.target 在所有浏览器中取得想要的值了。这就是在 TextAreaCounter 代码片段中,你只需要使用 ev.target.value 就可以正常工作的原因。与此同时,取消事件的 API 在所有浏览器中都通用了;event.stopPropagation() 和 event.preventDefault() 甚至在老版本 IE 浏览器中也可以生效。

这种语法轻松地把视图和事件监听绑定在一起。虽然其语法看起来就像传统的内联事件处理器一样,但背后的实现原理并非如此。事实上,React 基于性能考虑,使用了事件委托。

此外,React 在事件处理中使用驼峰法命名,因此你需要使用 onClick 代替 onclick。

如果你出于某种原因需要使用原生的浏览器事件,可以使用 event.nativeEvent,但估计你不太可能会用得上。

还有一件事情需要注意。onChange 事件(在文本框例子中已经用到)的行为和你预期中是一样的:当用户输入时触发,而不是像原生 DOM 事件那样,在用户结束输入并把焦点从输入框移走时才触发。2.7 props 与 state

现在你知道,当你需要在 render() 方法中显示组件时,可以访问 this.props 和 this.state 了。或许你会有疑问,两者应分别在何时使用呢?

属性是一种给外部世界设置组件的机制,而状态则负责组件内部数据的维护。因此,如果与面向对象编程进行类比的话,this.props 就像是传递给类构造函数的参数,而 this.state 则包含了你的私有属性。2.8 在初始化 state 时使用 props:一种反模式

在前面的一个例子中,我们在 getInitialState() 方法中使用了 this.props:getInitialState: function() { return { text: this.props.text, }; },

通常认为这种做法是反模式。理想情况下,你可以在 render() 方法中将 this.state 和 this.props 任意组合,以进行界面构建。但有时候,你想要传递一个值到组件中,用于构造初始状态。这种想法本身没什么不对,但如果组件的调用者以为属性(在之前的例子中是 text 属性)总是能保持最新,这种写法就有歧义了。为了符合语境,对命名作一点小改动就足够了。比如,把属性名 text 改成 defaultText 或者 initialValue:propTypes: { defaultValue: React.PropTypes.string }, getInitialState: function() { return { text: this.props.defaultValue, }; },第 4 章将说明 React 如何实现自己的 input 和 textarea 来解决这个问题。这和人们之前所了解的 HTML 知识有一些出入。2.9 从外部访问组件

在实际中,你不会总是从零开始构建一个 React 应用。有时候,你可能需要将一个现有的应用或网站逐步迁移到 React。幸运的是,React 的设计允许它和其他任何已存在的代码共存。毕竟,React 的原作者也并没有从头完全用 React 对一整个超大型应用(Facebook)进行重构。

让你的 React 应用和外界进行通信的一种方法,是在使用 ReactDOM.render() 方法进行渲染时,把引用赋值给一个变量,然后在外部通过该变量访问组件:var myTextAreaCounter = ReactDOM.render( React.createElement(TextAreaCounter, { defaultValue: "Bob", }), document.getElementById("app") );

现在你可以通过 myTextAreaCounter 访问组件的方法和属性,就像在组件内部使用 this 访问一样。你甚至可以在 JavaScript 控制台中操控这个组件(如图 2-9 所示)。

图 2-9:通过引用访问已渲染的组件

以下这行代码设置了新的 state 值:myTextAreaCounter.setState({text: "Hello outside world!"});

以下这行代码获取了 React 创建的父元素 DOM 节点的引用:var reactAppNode = ReactDOM.findDOMNode(myTextAreaCounter);

获取 DOM 结构中首个

节点。这也是你让 React 进行渲染的位置:reactAppNode.parentNode === document.getElementById('app'); // true

通过以下方法可以访问组件的属性和状态:myTextAreaCounter.props; // Object { defaultValue: "Bob"} myTextAreaCounter.state; // Object { text: "Hello outside world!"}现在你已经有权限从组件外部访问整个组件的 API。尽管如此,你还是应当谨慎使用这种超能力。也许当你需要获取节点的尺寸并确保其适配整个页面时,可以使用 ReactDOM.findDOMNode(),但这种情况确实出现得不多。即便你认为这样可以方便地修改那些不属于你的组件的 state,可这样做违背了 React 的初衷。假若组件并不能预料到外部的这些干扰,可能还会导致 bug 的产生。比如以下的代码虽然可以生效,但不推荐你这样做:// 反例 myTextAreaCounter.setState({text: 'NOOOO'});2.10 中途改变属性

正如你已经知道的,属性是配置组件的一种方式。因此在组件创建完成后,从外部改变组件的属性也是合理的。但你的组件应当作好应对这种场景的准备。

如果你回去看看之前例子中的 render() 方法,会发现我们在该方法中只用到了 this.state:render: function() { return React.DOM.div(null, React.DOM.textarea({ value: this.state.text, onChange: this._textChange, }), React.DOM.h3(null, this.state.text.length) ); }

如果你从外部改变了组件属性,不会对渲染产生影响。换句话说,当你进行如下操作时,文本框中的内容不会发生变化:myTextAreaCounter = ReactDOM.render( React.createElement(TextAreaCounter, { defaultValue: "Hello", // 之前的值为字符串"Bob" }), document.getElementById("app") );现在 this.props 的内容发生了变化(但界面没有变化):myTextAreaCounter.props; // 对象{defaultValue="Hello"}设置 state 确实会更新界面:尽管 myTextAreaCounter 会在 ReactDOM.render() // 反例 重新调用时被覆盖,但是myTextAreaCo应用的原有状态依然会保留。React 会在应用改变前unter.后作出协调setState({text: (reconciliation),且不会消'Hello'});除之前的数据。相反,React 仅作出最小限度的修改。但这种做法是不好的,因为这在更复杂的组件中可能会导致不一致的状态;比如打乱内部计数器、布尔型标记、事件监听器等。

如果你希望优雅地处理外部入侵(即属性改变),可以通过 componentWillReceiveProps() 方法实现:componentWillReceiveProps: function(newProps) { this.setState({ text: newProps.defaultValue, }); },

如你所见,这个方法会接收新属性对象,让你可以根据新属性设置 state。此外,还可以进行其他工作以确保组件状态保持正常。2.11 生命周期方法

上述代码片段用到的 componentWillReceiveProps() 方法是 React 提供的所谓生命周期方法之一。你可以使用生命周期方法监听组件的改变。除此之外,你可以实现的其他生命周期方法还包括以下几个。

componentWillUpdate()

当你的组件再次渲染时,在 render() 方法前调用(在组件的 props 或者 state 发生改变时会触发该方法)。

componentDidUpdate()

在 render() 函数执行完毕,且更新的组件已被同步到 DOM 后立即调用。该方法不会在初始化渲染时触发。

componentWillMount()

在新节点插入 DOM 结构之前触发。

componentDidMount()

在新节点插入 DOM 结构之后触发。

componentWillUnmount()

在组件从 DOM 中移除时立刻触发。

shouldComponentUpdate(newProps, newState)

这个方法在 componentWillUpdate() 之前触发,给你一个机会返回 false 以取消更新组件,这意味着 render() 方法将不会被调用。这在性能关键型的应用场景中非常有用。当你认为变更的内容没什么特别或者没有重新渲染的需要时,可以实现该方法。要决定是否更新,只需比较 newState 参数和目前的状态 this.state 的区别,以及 newProps 参数和目前的属性 this.props 的区别。当然,也可直接认为该组件是静态的而无需更新。(随后你会见到相关例子。)

试读结束[说明:试读内容隐藏了图片]

下载完整电子书


相关推荐

最新文章


© 2020 txtepub下载