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

探索React:组件间通信过程解析

HTML文档下载 WORD文档下载 PDF文档下载
《The React.js Way》系列博文重点分享React所具特性及最佳开发实践。本文为第二篇的译文,重点探讨了React组件间相互通信过程。

近日,RisingStack CTO Péter Márton正在陆续发表《The React.js Way》系列博文,第一篇文章以分享React.js的核心入门知识(中文译文)为主,并讨论了虚拟DOM的概念,以及如何使用组件的思维方式来思考开发的基础上。接下来,需要将它们组合起来运用到实战中去, 第二篇文章则以此为出发点,探讨了React的组件间是如何进行相互通信的。感谢景庄对第二篇文章的翻译,内容如下:

组件即是函数

对于一个独立组件而言,你可以把它看成是一个JavaScript函数。对于函数而言,当你通过传递参数调用函数时,函数会返回给你一个值。 相比之下,对于React组件而言,道理是相似的,你传递属性给组件,而组件则会返回一个被渲染好的DOM。通过传递不同的数据, 相应的你会得到不同的响应。这个过程也就使得React组件能够得到极大的复用,并且你可以很轻松的在应用中重用和组装这些组件。 这种思想实际来源于函数式编程,但其并不在本文的讨论范围中。如果你感兴趣的话,那我强烈建议你阅读Mikael Brevik的 《 Functional UI and Components as Higher Order Functions》, 它可以帮助你更好的理解这个话题。

自上而下渲染

目前为止,我们可以轻松地通过组装组件的方式来构建应用,但此之前,在组件中并没有包括数据。在第一篇文章中,我们讨论过可以在组件层次中的根组件中通过将数据作为参数传递给组件,并且通过层层传递的方式将数据传递给下层组件,也就是说,你在顶层传递数据,它可以一层一层地往下传递, 这个过程,我们称之为自上而下的渲染。


从上层组件往下层组件传递数据其实很简单,但是,如果下层组件发生了某些变化,我们如何通知上层组件呢?例如,用户点击了某个按钮? 我们需要某个东西来存放应用程序的状态数据,能够在状态发生变化的时候去通知所发生的变化。新的状态应该能够被传递给根节点 (最上层节点),然后应该再次发起自上而下的渲染,从而重新生成(渲染)DOM。为了解决这个问题,Facebook提出了Flux架构。

Flux架构

你可能已经听过什么是Flux,也了解它是一种类似于MVC的应用程序设计架构,因此本文不会过多的去探讨什么是Flux,感兴趣的话, 可以阅读《 Flux Inspired libraires with React》这篇文章。

构建用户界面的应用程序架构 —— Facebook Flux

简单总结下:Flux倡导的是单向数据流的原则,在这种架构下,通过Store存放应用程序的状态数据。当应用状态发生变化时,Store可以发出事件,通知应用的组件并进行组件的重新渲染。另外,Dispatcher起到中央hub的作用,它为组件(View)和Store构建起了桥梁。此外,你可以在组件上调用action,它会向Store发起事件。Store正是通过订阅这些事件,并根据事件的触发来改变应用程序的内部状态的。


PureRenderMixin

目前对于我们的应用而言,我们通过一个数据store来存放应用的实际状态。我们可以和这个store进行通信,将数据传递到我们的应用上, 当组件获取新的数据后,进而对视图进行重新渲染。这听起来很赞,但总感觉会经历很多次的渲染,的确是这样的!需要记住的是:组件的层次关系和自然而下的渲染,一切都会根据新的数据来进行响应,做出相应的变化。

在这之前的文章中,我们讨论过虚拟DOM通过一种更为优雅的方式降低了DOM操纵带来的性能损耗,但这并不意味着我们就不需要自己手动进行性能优化了。 对此,基于当前数据和新来的数据之间的差异,我们应该能够告诉组件对于新来的数据是否需要进行视图的重新渲染(如果数据没有发生变化,应该不再重新渲染)。在React的生命周期中,你可以借助shouldComponentUpdate来达成这一目的。

幸运的是,在React中有一种被称为PureRenderMixin的Mixin模式,它可以用来对新的属性和之前的属性进行对比,如果是数据没有发生变化,就不再重新渲染。在内部实现上,它也是基于shouldComponentUpdate 方法的。

这听起来很赞,但遗憾的是,PureRenderMixin并不能很好地进行对象的比较。它只会检查对象引用的相等性(===),也就是说, 对于有相同数据的不同对象而言它会返回false。

boolean shouldComponentUpdate(object nextProps, object nextState)
如果shouldComponentUpdate返回的是false的话,render函数便会跳过,直到状态再次发生改变。(此外,componentWillUpdate和componentDidUpdate也会被跳过)。对于上面所说的问题,我们可以简单的举个例子来说明,有代码如下:

var a = { foo: 'bar' };  var b = { foo: 'bar' };a === b; // false  
可以看到,数据是相同的,但它们隶属于不同对象的引用,因此返回的是false,也因此组件仍然会进行重新渲染,显然这没有达到我们的目的。如果我们想要达成设想的效果(即对于相同数据而言,组件不再重新渲染),我们就需要在原始的对象上进行数据的修改:

var a = { foo: 'bar' };  var b = a;  b.foo = 'baz';  a === b; // true  

虽然实现一个能够进行深度对象比较的mixin来代替引用检查并不困难,但是,考虑到React调用shouldComponentUpdate方法非常频繁,并且对象的深度检查代价较高,所以React选择了这种对象引用比较的方案。

我非常建议你阅读Facebook官方的 有关React应用高级性能的文档。

不变性 Immutability

如果我们的应用状态是一个单一的、大的、嵌套的对象(类似于Flux中的Store),那么上面提到的问题会逐渐升级。

所以当对象的内容没有发生变化时,或者有一个新的对象进来时,我们倾向于保持对象引用的不变。这个工作正是我们需要借助Facebook的Immutable.js来完成的。

不变性意味着数据一旦创建就不能被改变,这使得应用开发更为简单,避免保护性拷贝(defensive copy),并且使得在简单的应用逻辑中实现变化检查机制等。

下面通过一个例子来解释下上面的话。比如,有如下的代码片段:

如上,我们可以使用===来通过引用来比较对象,这意味着我们能够方便快速的进行对象比较,并且它能够和React中的PureRenderMixin 兼容。基于此,我们可以在整个应用构建中使用Immutable.js。也就是说,我们的Flux Store应该是一个具有不变性的对象,并且我们通过 将具有不变性的数据作为属性传递给我们的应用程序。

现在我们回到前面的代码片段来重新想象我们应用程序的组件结构,可以用下面这张图来表示:

如上,我们可以使用===来通过引用来比较对象,这意味着我们能够方便快速的进行对象比较,并且它能够和React中的PureRenderMixin 兼容。基于此,我们可以在整个应用构建中使用Immutable.js。也就是说,我们的Flux Store应该是一个具有不变性的对象,并且我们通过 将具有不变性的数据作为属性传递给我们的应用程序。

现在我们回到前面的代码片段来重新想象我们应用程序的组件结构,可以用下面这张图来表示:

如上,我们可以使用===来通过引用来比较对象,这意味着我们能够方便快速的进行对象比较,并且它能够和React中的PureRenderMixin 兼容。基于此,我们可以在整个应用构建中使用Immutable.js。也就是说,我们的Flux Store应该是一个具有不变性的对象,并且我们通过 将具有不变性的数据作为属性传递给我们的应用程序。

现在我们回到前面的代码片段来重新想象我们应用程序的组件结构,可以用下面这张图来表示:

var stateV1 = Immutable.fromJS({    users: [    { name: 'Foo' },    { name: 'Bar' }  ]});var stateV2 = stateV1.updateIn(['users', 1], function () {    return Immutable.fromJS({    name: 'Barbar'  });});stateV1 === stateV2; // false  stateV1.getIn(['users', 0]) === stateV2.getIn(['users', 0]); // true  stateV1.getIn(['users', 1]) === stateV2.getIn(['users', 1]); // false  

如上,我们可以使用===来通过引用比较对象,这意味着我们能够方便快速地进行对象比较,并且它能够和React中的PureRenderMixin 兼容。基于此,我们可以在整个应用构建中使用Immutable.js。也就是说,我们的Flux Store应该是一个具有不变性的对象,并且我们通过将具有不变性的数据作为属性传递给我们的应用程序。

现在我们回到前面的代码片段来重新想象我们应用程序的组件结构,可以用下面这张图来表示:


从上面的图形中你可以发现,在应用状态发生变化后,只有红色的部分会被重新渲染,因为其他部分的引用数据并没有发生变化。也就是说, 只有根组件和其中一部分的user组件会被重新渲染。

基于这种不变性,能够优化React组件的渲染路径,并通过这种方式来重新思考我们的应用构建和应用性能优化。此外,得益于虚拟DOM, 它能够让React应用比传统应用来得更加高效与快速。(责编:陈秋歌)

译者简介:景庄,前端工程师,关注Node.js、前端工程化。个人博客:http://wwsun.github.com。


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

也可参加CSDN前端大讲堂(微信公开课),享受高含金量在线公开课,与专家讲师在线切磋交流。

如何加入CSDN前端大讲堂?由于该群目前已超过人数限制,所以您首先不得不 扫描下面二维码,加CSDN编辑陈秋歌为好友,然后请她邀请您加入CSDN前端大讲堂微信群。加好友时,请务必注明“申请加入CSDN前端大讲堂”。


VB使用 WIN95 的选择目录对话框 VB使用INI文件 VB使用WriteFile 块读写数据 VB使用历史文件记录 VB使用内存映射文件加快文件操作速度 VB数据报表设计器在多层结构开发的应用 VB突破 TextBox 32K 的限制 VB拖拽节点时实现目录树自动翻滚 位图文件内部初探-VB资料 VB文本的加密与解密 VB显示盘中所有的目录 VB压缩MDB文件 一个移动文件的简单方法-VB资料 VB移动文件到回收站 VB隐藏文本框控件的环境菜单(又一方法) VB隐藏文本框控件的环境菜单 VB用API复制移动文件 VB用OleDragdrop事件接受拖放文件 用VB进行文本文件的再处理 用VB开发应用程序如何使用INI文件 用VB实现文件查找功能 VB用Winsock控件实现文件的下载 VB用两分法搜索列表框或组合框中的数据 在 ListBox 之中, 如何检测鼠标所在位置的选项? -VB资料 在 Textbox 中,录入 N 个字符后移到下栏-VB资料 在 VB 中控制 Word 在GotFocus时快速选择文本 -VB资料 在VB中使用文件对象 在VB中使用艺术字 在VB中引用.dbf及索引文件 在Windows操作系统中改变文件打开方式-VB资料 代理不能定时执行,请指教,谢谢。 怎样与外部数据库建立联合查询? 如何接受来自vbscript的字符数据列表 怎么在Gtk+的gnomemessagebox显示中文? (在线等待,急!)在vc中怎么使用datagrid控件 我使用的是odbc访问数据库 好急的问题,有关于SMS的接收字符处理问题,想了好几天没有结果 那位兄弟手头上有ASP.NET高级编程的电子书? DataGrid 控件问题,帮帮我把,朋友! automount? 一个比较难的问题! 关于datagrid的问题 在线等待 在cmd编辑器中用java运行已编译的文件运行不成功怎样解决 各位帮我解决一下这个问题!!!谢谢 关于ResourceManager的疑惑? 两台机器无法访问? 大家有没有听说过zebudom.js这个javascript的API?请问哪里可以下载它? 模块的连接 如何用php开发一个在线语音聊天室? 请问:有谁能提供Microsoft Project 2002简体中文专业版下载地址????急用!!!!!! 《The C++ Programming Language》有没有中译版? 请高手帮我看看: session的范围 硬件加、解密卡合作 请问那里能下到C或者C++的编译环境? 我的网页做好了,在我自己的机子上显示的很好看,在别的机子上有的显示的和在我的机子上显示的一样,很不错,但在有些机子上显示就变形了 怎样在文件中查找指定的字串? 为什么这两个查询都不能运行呢? 请教有关比对数据库的思路 运行结果出错!!!!!!!!!! google主页的问题(在线) (在线等待,急!)对话框中画图,超过了对话框大小,但是滚动条不能用 jbuilder7+jboss的配置问题? 求教:用UML做分析设计工具、用JAVA开发的一个办公管理系统的详细时间节点计划书。 數據庫數據顯示問題///急,在線等!!!!!個位幫幫忙? 讨论一下,eregi和strpos 为什么这两个查询都不能运行呢? 集成多文件夹操作窗口的软件有吗?有的请发QQ;6138215 怎么获得checkbox组中被选中的部分? sybase表中有没有自动编号的字段啊? 问一个很菜的问题?(在线等……) DOMINO的B/S开发:如何自动更新一页面中的多分类新闻标题AS WWW。WXRB。COM 如何用一根电话线让两台电脑同时上网 急!!“SQLserver不存在或访问被拒绝”怎末回事? 有没有防止关于用户未经登陆,直接访问的好办法,和思想?仁者见仁! 请问芯片的封装主要有哪几种? servlet问题 关于数据库的问题? URL,HTTP含义是什么? oracle8.17安装好后,无法使用!!!俺只有50分??? 请问高手关于发布的问题 吃花生应不应该吃花生皮 麻烦大家看下本世纪最难的物理题帮帮着急的人吧, 1.汽车从A地开往B地,共用了两小时,第1小时中行驶80千米,第2小时中运行了60千米,两种情况中平均速度各多大?在总的过程中的平均速度多大?2.高速路上为了避免发生汽车追尾事故,有关部门在公 “三面红旗会甘肃”有何历史意义? “古城遵义”在党的历史上发生过什么重大事件?其意义是什么? 花生内的皮的好处 关于六国论的的课文 邀请别人的用语(英语) 功成名就是什么意思 水下地形图的意思 写一个神话故事主要内容,要简介 求梦寐以求和功成名就的意思,必采纳 六国论原文 邀请别人的英语用语(急!) 急流通退,功成名就的意思是什么呢? 标准原文准确的原文, 临危不惧.勇往直前.等的成语有那些?是五年级上册的语文书里的成语. 功成名就的解释 六国论 原文 翻译成中文:Bachelor film project 2012 from The Animation Workshop. 35、6岁的人最想的是什么? 以“六国论”写片文章!以六国论写片文章,文体不限,字数200左右就可以了!谈论下六国是怎么灭亡的!要群面阐述!超不200字也没关系! 爱的教育中体现了哪些种情感 画出你想象中的海边美景怎么画 功成名就的意思是什么? 腊八粥 阅读题腊 八 粥冰 心从我能记事的日子起,我就记得每年农历十二月初八,母亲就给我们煮腊八粥.这腊八粥是用糯米、红糖和十八种干果掺在一起煮成的.干果里大的有红枣、桂圆、核 窃读记窃读指什么 成语什么于途 如何形成一个团结的班风在高中当班长很窝囊 窃读记,窃表现在哪 成语什么途? 窃读记作者怎样窃读以及作者的心情 古人的书信具体有哪几种形式 道()途()的成语有哪些 《窃读记》作者为了窃读不被赶,有哪些方法? 功成名就的‘就’是什么意思? 填成语()()于途? 《爱的教育》英文的读后感一百字左右,要有中文翻译 七一红色瑞金的由来 成语:日()途() 为什么很多著名的科学家信仰上帝我一直很纳闷的是为什么很多西方人都相信有上帝,尤其是一些在科学界取得过重大发现的科学家,他们的科学知识一定要比我们多得多,那为什么还会相信上 图书馆 磁条图书馆里的书除了反面右下角的条形码,还有就是书的第一或第二叶人工贴的条形码(也就是如果你要借的话,工作人员会用东西把这个人工贴的条形码照一下).把这个人工贴的条 给家乡孩子的一封信 你如何理解一心为自己,一身为自己的人这句话 y=根号(ax2-ax+1)的定义域是R,则实数a的取值范围是 不假思索和功成名就的意思 请问下有人知道物理问题,紧急j谁知道 非常谢谢大伙了7GN 若函数y=根号下(ax2-ax+1/a)的定义域是R,求实数a的取值范围. 《海滨仲夏夜》作者描写月下的海滩时重点写了什么?表达了作者怎样的思想感情? 紧急有人了解的告诉下哟, 函数f(x)=[3次根号(x+4)]/ax^2+4ax+3的定义域R,则a取值 老( )识途!填成语 请问有谁知道物理题目n有会的人说下嘛,感谢你们了5Yq 欧美人科技发达,但为什么大部分都信上帝?最近的100年,人们几乎可以用科学来解释任何自然界发生的事.特别是欧美.科技如此发达.为什么他们还相信有神呢?他们是真的相信有神的存在?还是 补充成语,汗〈〉充栋 有538箱鲜奶,每辆货车一次运62箱,每次大约需要多少辆这样的货车? 书信作文 什么什么识途的成语 于丹论语心得后面的原文全吗 辩论:该不该见义勇为 (正方)可不可以具体点! 麻烦给看下这两个物理题好吗~ 《沁园春·雪》中用“北国风光,千里冰封,万里雪飘”的词句来描述雪景,形成这种自然景象的主要物态変化是( 网曝湛江国资委官员带女下属开房 视频广东湛江国资委官员被曝与女下属开房 韩媒称韩国海警截获三艘“非法捕捞”中塑料袋威胁欧洲环境 欧盟计划对其征收澳华裔女专家制乳癌病例数据库 拯救数美国新泽西一商场发生枪击事件 暂无人曝孙杨因同乘者不满赔偿金才报警 托人美国国务卿克里访波兰 有望就监听事件穆尔西受审质疑审判合法性 埃及民众意发改委:雾霾天气几乎常态化 通过5-雾霾影响生殖能力,不能当成“雷语”加拿大一名刑满性犯罪者潜逃至美国又面日本一企业官员疑挪用24亿日元 被同消息称利比亚首都发生激烈交火 枪声持新加坡拟开发路边停车电子收费新系统孙杨可自选拘留时间 新女友浮出水面亦日本一企业官员疑挪用24亿日元 被同加拿大一名刑满性犯罪者潜逃至美国又面麻生积极扩大外国游客免税品范围 以吸塑料袋威胁欧洲环境 欧盟计划对其征收盘点孙杨这些年惹的事 无证驾驶 耍大用汽油当燃料烤衣服烧毁6间门面获刑3长沙县星沙天然气用户可预约免费入户安张硕辅在汛期心系高考师生 要求各地坚浏阳市澄潭江镇遭遇近50年最严重洪水长沙县民情接待站深入实际听民声地下长沙竖向分层立体综合开发13岁少年攀玩石柱 被几百斤重石雕砸长沙市天心区举行“欢乐潇湘·乐在天心企业面试流行“能力素养测试”阿根廷华人超市遭两持枪歹徒抢劫 损失澳洲去年吸纳移民数量创新纪录 技术移南开大学常健:走向更全面、更公平的经回报祖国理所应当 记巴西侨领尹相丛日媒:不可忽视的舌尖上的中日两国交流分类,职教“第三春”?望城打造世界级休闲旅游峰会品牌(图)长沙多警联动强化社会面整体防控长沙县委书记杨懿文:聚焦“四风”问题长沙县老人足不出户可免费看病体检收养22年的女孩突发白血病 家人为救清除“桌霸” 湖南烈士公园拆掉园区内
备案号:鲁ICP备13029499号-2 说三道四 www.s3d4.cn 说三道四技术文摘