说三道四技术文摘-感悟人生的经典句子
说三道四 > 文档快照

React首部经典图书推荐:全程经典实例,360度剖析React.js

HTML文档下载 WORD文档下载 PDF文档下载
React.js基于Virtual DOM重新定义了用户界面的开发方式,革新了大家对前端框架的认识,将PHP风格的开发方式迁移到客户端应用开发。《React:引领未来的用户界面开发框架》作为该领域的首部作品已正式出版。

【编者按】Facebook 2014年推出了开源框架React.js,《React:引领未来的用户界面开发框架》作为该领域的首作,由多位一线专家精心撰写,采用一个全程实例全面介绍和剖析了ReactReact.js 的方方面面。下面为该书的节选内容。

动画

动画可以让用户体验变得更加流畅与自然,而React 的TransitionGroup 插件配合CSS3 可以让我们在项目中整合动画效果的工作变得易如反掌。

通常情况下,浏览器中的动画都拥有一套极其命令式的API。你需要选择一个元素并主动移动它或者改变它的样式,以实现动画效果。这种方式与React 的组件渲染、重渲染方式显得格格不入,因此React 选择了一种偏声明式的方法来实现动画。

CSS 渐变组(CSS Transition Group)会在合适的渲染及重渲染时间点有策略地添加和移除元素的class,以此来简化将CSS 动画应用于渐变的过程。这意味着唯一需要你完成的任务就是给这些class 写明合适的样式。

间隔渲染以牺牲性能为代价提供了更多的扩展性和可控性。这种方法需要更多次的渲染,但同时也允许你为CSS 之外的内容(比如滚动条位置及Canvas 绘图)添加动画。

CSS 渐变组

看一下我们的示例程序——问卷制作工具——是如何在问卷编辑器中渲染问题列表的。

<ReactCSSTransitionGroup transitionName='question'>{questions}</ReactCSSTransitionGroup>

ReactCSSTransitionGroup 是一款插件,它在文件最顶部通过var ReactCSSTransitionGroup= React.addons.ReactCSSTransitionGroup; 语句被引入。

它会自动在合适的时候处理组件的重渲染,同时根据当前的渐变状态调整渐变组的class 以便实现组件样式的改变。

我们有一个贯穿全书的示例项目,一个问卷制作工具,你可以在https://github.com/backstopmedia/bleeding-edge-sample-app 阅读全部源码。

给渐变class 添加样式

按照惯例,为元素添加transitionName='question' 意味着给它添加了4 个class:questionenter、question-enter-active、question-leave 及question-leave-active。当子组件进入或退出ReactCSSTransitionGroup 时,CSSTransitionGroup 插件会自动添加或移除这些class。

下面是问卷编辑器中使用到的渐变样式:

.survey-editor .question-enter {transform: scale(1.2);transition: transform 0.2s cubic-bezier(.97,.84,.5,1.21);}.survey-editor .question-enter-active {transform: scale(1);}.survey-editor .question-leave {transform: translateY(0);opacity: 0;transition: opacity 1.2s, transform 1s cubic-bezier(.52,-0.25,.52,.95);}.survey-editor .question-leave-active {opacity: 0;transform: translateY(-100%);}

注意这些.survey-editor 选择器并不是ReactCSSTransitionGroup 需要的,它们只是简单地用来确保这些样式只会在编辑器里生效。

渐变生命周期

question-enter 与question-enter-active 的区别在于,question-enter 这个class 是组件被添加到渐变组后即刻添加上的,而question-enter-active 则是在下一轮渲染时添加的。这样的设计让你能轻松地定义渐变开始时的样式、结束时的样式以及如何进行渐变。

举个例子,当问卷编辑器中的问题被添加到列表时,它们首先被用scale(1.2) 放大,然后渐变到正常的scale(1) 状态,总共耗时0.2 秒。这就创造出了一种你看到的跳出来的效果。

默认情况下,渐变组同时启用了进入和退出的动画,你可以通过给组件添加transitionEnter={false} 或transitionLeave={false} 属性来禁用其中一个或全部禁用。除了可以控制选择哪些动画效果外,我们还能根据一个可配置的值在特定的情况下禁用动画,像这样:

<ReactCSSTransitionGroup transitionName='question'transitionEnter={this.props.enableAnimations}transitionLeave={this.props.enableAnimations}>{questions}</ReactCSSTransitionGroup>

使用渐变组的隐患

使用渐变组时主要有两个重要的隐患需要注意。

首先,渐变组会延迟子组件的移除直到动画完成。这意味着如果你把一个列表的组件包裹进一个ReactCSSTransitionGroup 中,却没有为transitionName 属性指定的class 明确任何CSS,这些组件将永远无法被移除——甚至当你尝试不再渲染它们时也不可以。

其次,渐变组的每一个子组件都必须设置一个独一无二的key 属性。渐变组使用这个属性来判断组件究竟是进入还是退出,因此如果没有设置key 属性动画可能无法执行,同时组件也会变得无法移除。

注意,即使渐变组只有一个子元素,它也需要设置一个key 属性。

间隔渲染

使用CSS3动画能够获得巨大的性能提升并拥有简洁的代码,但它们并不总是解决问题的正确工具。有些时候你必须要为较老的、不支持CSS3 的浏览器做兼容,还有些时候你想为

CSS属性之外的东西添加动画,比如滚动条位置或Canvas 绘画。在这些情况下,间隔渲染能够满足我们的要求,但是相比CSS3 动画来说,它会带来一定的性能损耗。

间隔渲染最基本的思想就是周期性地触发组件的状态更新,以明确当前处于整个动画时间中的什么阶段。通过在组件的render 方法中加入这个状态值,组件能够在每次状态更新触发的重渲染中正确表示当前的动画阶段。

因为这种方法涉及多次重渲染,所以通常最好和requestAnimationFrame 一起使用以避免不必要的渲染。不过,在requestAnimationFrame 不被支持或不可用的情况下,降级到不那么智能的setTimeout 就是唯一的选择了。

使用requestAnimationFrame 实现间隔渲染

假设你希望使用间隔渲染将一个div 从屏幕的一边移向另一边,可以通过给它添加position: absolute 并随着时间变化不停更新left 或top 属性来实现。根据消耗时间内的变化总量,用requestAnimationFrame 来实现这个动画应该可以得出一个流畅的动画。

下面是具体实现的例子。

var Positioner = React.createClass({getInitialState: function() { return {position: 0}; },resolveAnimationFrame: function() {var timestamp = new Date();var timeRemaining = Math.max(0, this.props.animationCompleteTimestamp- timestamp);if (timeRemaining > 0) {this.setState({position: timeRemaining});}},componentWillUpdate: function() {if (this.props.animationCompleteTimestamp) {requestAnimationFrame(this.resolveAnimationFrame);}},render: function() {var divStyle = {left: this.state.position};return <div style={divStyle}>This will animate!</div>}});

在这个例子中,组件的props 中设置了一个名为animationCompleteTimestamp 的值,它和requestAnimationFrame 的回调中返回的时间戳一起被用来计算剩余多少位移。计算的结果存在this.state.position 中,而render 方法会用它来确定div 的位置。

由于requestAnimationFrame 被componentWillUpdate 方法调用,所以只要组件的props有任何的变动(比如改变了animationCompleteTimestamp)它就会被触发。它又包含了在resolveAnimationFrame 中的this.setState 调用。这意味着一旦animationComleteTimestamp被设置,组件就会自动调用后续的requestAnimationFrame 方法,直到当前时间超过了animationCompleteTimestamp 为止。

注意,这套逻辑只在基于时间戳的情况下成立。对animationCompleteTimestamp 所做的改变会触发逻辑,而this.state.position 的值完全依赖于当前时间与animationCompleteTimestamp的差。正因如此,render 方法可以自由地在各种动画中使用this.state.position,包括设置滚动条位置、在canvas 上绘画,以及任何中间状态。

使用setTimeout 实现间隔渲染

尽管requestAnimationFrame 总体上能够以最小的性能损耗实现最流畅的动画,但它在较老的浏览器上是无法使用的,而且它被调用的次数可能比你想象的更频繁(也更加无法预测)。在这些情况下你可以使用setTimeout。

var Positioner = React.createClass({getInitialState: function() { return {position: 0}; },resolveSetTimeout: function() {var timestamp = new Date();var timeRemaining = Math.max(0, this.props.animationCompleteTimestamp- timestamp);if (timeRemaining > 0) {this.setState({position: timeRemaining});}},componentWillUpdate: function() {if (this.props.animationCompleteTimestamp) {setTimeout(this.resolveSetTimeout, this.props.timeoutMs);}},render: function() {var divStyle = {left: this.state.position};return <div style={divStyle}>This will animate!</div>}});

由于setTimeout 接受一个显式的时间间隔,而requestAnimationFrame 是自己来决定这个时间间隔的,因此这个组件需要额外依赖一个变量this.props.timeoutMs,以此来明确要使用的间隔。

开源库ReactTweenState 基于这种动画方式提供了一套方便的抽象接口。

总结

使用这些动画技术,你现在可以:

1. 在状态改变过程中,使用CSS3 和渐变组高效地应用渐变动画。

2. 使用requestAnimationFrame 为CSS 之外的东西添加动画,如滚动条位置或Canvas绘画。

3. 当requestAnimationFrame 不被支持时降级到setTimeout 方法。


本文摘自《React:引领未来的用户界面开发框架》,电子工业出版社出版。

2014年横空出世的由Facebook推出的开源框架React.js,基于Virtual DOM重新定义了用户界面的开发方式,彻底革新了大家对前端框架的认识,将PHP风格的开发方式迁移到客户端应用开发。其优势在于可以与各种类库、框架搭配使用。《React:引领未来的用户界面开发框架》是这一领域的首作,由多位一线专家精心撰写,采用一个全程实例全面介绍和剖析了React.js 的方方面面,适合广大前端开发者、设计人员,及所有对未来技术趋势感兴趣者阅读。

欢迎加入CSDN前端交流群:218126086,进行前端技术交流。 

移动开发者必须了解的10大跨平台工具 不差钱:30+收购案,170亿美元投资,IBM再度出手收购Cloudant 微软反击谷歌:Windows授权费降七成+硬件要求减少一半 [测试] 你的HTML5知识够金质吗? 基于OpenStack的虚拟机在线迁移 当64bit遇上8核心:高通发布Snapdragon 615 深圳Maker Faire创客市集:国内外创客组团来参展 腾讯正式发布QQ浏览器微信版 摩托罗拉今年推智能手表,有望提高续航能力 众筹未来必拥抱众智 果合报告:iOS趋势及手游开发六大核心策略 无视OpenStack的前车之鉴,SAP等毅然支持Cloud Foundry 轻松搞定TB级数据,开源GraphLab突破人类图计算“极限值” 英特尔至强E7 v2处理器:2倍性能提升,3倍内存容量,4倍I/O带宽 著名工业设计师Yves B&#233;har:“我们并不需要三星智能手表。” 跨平台的.NET运行环境 Mono 3.2.7发布! Google石博盟:抓住全球化和移动化的机遇 ShareSDK针对Unity发布社交化组件 2014 CocoaChina开发者大会将公布触控奖学金等高校合作计划 中低端智能手机热销,未来市场或主打价格战 Facebook开源flint:一个用D语言编写的C++静态代码分析器 AMD携手BlueStacks,下半年推出零售版双操作系统 历时6年 Github发布基于Web的桌面文本编辑器:Atom Ratchet:构建移动应用原型,新版支持Android 13个最狂帅炫酷的前沿科技研究项目 打动面试官的五大技能 乐视TV和NBA签约三年互联网电视版权 首度披露大屏运营策略 支撑4.5亿活跃用户的WhatsApp架构概览 免费使用Windows?微软推Windows 8.1 with Bing实验项目 C/C++开发者必不可少的15款编译器+IDE Amazon推荐,Facebook追踪,大数据时代的“狗仔队” 有问题的问题1 有问题的问题 安装visual studio.net 2003 的问题? 急件!请教了,如何在一个字符串中提取第n次出现的字符? weblogic及EJB属于中间层的吗? 到水园第一件事就是看看斑竹有没有换,嘻嘻,还有谁也是这样的? win2000装好后,设了本地连接的属性,和别的机器一样的设,可就是PING 不通网关 哪有“VB.NET高级编程”和“ADO.NET高级编程”下载?? 请各位帮忙找一个用asp.net写的日历,急用 小弟是菜鸟,请问一下svrmgrl是什么,9I中有吗? 文章分页,而且文章中有大小不等的图片,该如何去做 求《三国霸业2》简体版下载地址? 诸位高手,我碰到一个很棘手ASPNETMENU的问题!急需解决!!(100分)献上! vfw下的视频采集和图象截取的问题请教! 求 《家园-惊世浩劫》简体版 关于浏览器的问题 pb如何调用word文挡? 在使用mfc时选择不同语言,怎么最后编译执行时有??符号(在菜单中) 网络共享安全问题!!!!!!!!!!!!! 我是第一次尝试做网站,碰到了问题,能帮帮我吗? 电话号码的正确性问题? 求教c#中datagrid表格设置 高分求远程开机源代码 希望大家给出: 时间的各种单位(包括汉字名称和英文缩写)及它们的进率关系; 专家近来看一下,很有针对性! 对《c# Primer Plus中文版》书的批判!!!!! 谁能提供teechart在pb中的使用帮助 是否有记录传真机传真的资料(包括传真号码,传真时间,内容) 是否有记录传真机传真的资料(包括传真号码,传真时间,内容) 急救:如何回复fdisk删除的分区 请各位帮忙找一个用asp.net写的日历,急用 我想了解‘Bug 列表‘是怎么回事,最好有例子 各位大哥请帮帮我,如何将下面的vbs转换到c#,不胜感激! 如何控制DataList显示的记录数 请教做过基于snmp方式的入侵检测系统的哥们 !!!!!!! 架构模式知多少? 请教做过基于snmp方式的入侵检测系统的哥们 !!!!!!! 请教各位大侠一个问题?? 请教做过基于snmp方式的入侵检测系统的哥们 !!!!!!! 一个初学者的麻烦! 帮忙写个求时间的函数, 请教做过基于snmp方式的入侵检测系统的哥们 !!!!!!! 二叉查找树的问题(好难啊!求救) 怎么在网页中添加一个生成EXCEL按钮 请教做过基于snmp方式的入侵检测系统的哥们 !!!!!!! 堆的一个问题?? 关于对话框的处理问题!!!!!!!!! 笔记本电脑如何进CMOS设置?我按Del不行,我想设光区启动,机子是联想的。急 2000说有文件被替换为不可识别的格式。? 关于vs中的水晶报表版权的问题 子网掩码到底有什么用? 假如我去年的营业额是1万,然后我今年的是1万2,那我今年的同比增长多少?怎么计算的?告诉我计算公式才好 amplify 放大这个单词 谁能帮我想点办法记住 amplify(放大声音)的反义词是? “你给我一种不安的感觉”用英语怎么说? "不积硅步无以至千里,无已至千里;不积小流,无已成江海" 翻译成英语怎么讲? 我想了解下,嗳气有些什么症状显示是嗳气呢?嗳气了怎么办?嗳气症状有哪些呀? 烦躁的英文 先化简下面的代数式,再求值 (a+2)(a-2)+a(4-a),其中a=根2+1. Not everyone is confident of himself.(改为同义句) Not everyone 1.——2.——3.——(三个空)himself He is ----- (confident) of victory 过故人庄的原文 中国成功连任联合国经社理事会成员法国巴黎CAC40股指下跌成品油调价窗口今日开启 机构预测每升国内成品油价今迎调价窗口 “两连跌”美国私营部门新增就业岗位创6个月新低陕西“房姐”案今日二审宣判 一审未提李某某强奸案二审延期 张起淮承认担任杨澜提问朗朗\"工作有何意义\"惹争俄达吉斯坦共和国首府发生爆炸袭击俄罗斯将提高远东石油管道输油能力巴基斯坦奎达发生爆炸4人死亡江西宜黄工业园党工委书记聂发来被“双全国英烈讲解员网络电视大赛举行中科大固态量子芯片研究取得重要进展 土耳其边境城市发生爆炸27死百余伤 徐守盛谈扶贫开发:必须坚定不移走精准江西曝6起违反八项规定精神案例 官员成思危同志遗体在京火化 习近平等到八第六批赴毛里求斯援外中国青年志愿者在通讯:探寻蒙古族数百年文化延续:别力成思危同志遗体在京火化 习近平等到八土耳其靠近叙利亚小镇发生爆炸伤亡惨重末世之三分钟英雄前夫高攀不起重生末世江筱农家厨娘宅女的随身庄园子时武动苍穹未来多子多福神牧游戏规则步步莲华上海当代艺术馆旅游OPA百货旅游徐家汇天主教堂旅游漕溪公园旅游徐家汇公园旅游佘山国家森林公园旅游红坊旅游顾村公园旅游人民公园旅游万国建筑群旅游华东政法大学旅游
备案号:鲁ICP备13029499号-2 说三道四 www.s3d4.cn 说三道四技术文摘