探索React生态圈
前端之家收集整理的这篇文章主要介绍了
探索React生态圈,
前端之家小编觉得挺不错的,现在分享给大家,也给大家做个参考。
2004年,对于前端社区来说,是里程碑式的一年。Gmail横空出世,它带来基于前端渲染的原生应用级别的体验,相对于之前的服务端渲染网页可谓提升了一个时代,触动了用户的G点。自此,前端渲染的网站成为无数开发者追逐的方向。
为了更好地开发前端渲染的“原生级别的”网站,包括Backbone和Angular在内的一系列前端框架应运而生,并迅速获得了大规模的采用。但是很快地,新的性能和SEO问题也接踵而来。几经尝试后,Twitter甚至从前端渲染重回服务器渲染,而Strikingly也面对过同样棘手的问题。
2014年,React进入我们的视线。让人耳目一新的是,对于其他开源框架遇到的种种问题,React都自信地给出了解答。几乎没有犹豫,我们开始使用React来重构Strikingly。若干年后,当我们回望,也许会发现,2014年也是前端社区里程碑式的一年。
React简介
React究竟是什么?Facebook把它简单低调地定义成一个“用来构建UI的JavaScript库”。这个定义也许会让我们联想到许多JavaScript模板语言(比如Handlebars和Swig),或者早期的控件库(比如YUI和Dojo),但是React所基于的几个核心概念使它与那些模板和控件库迥然不同。事实上这几个核心概念非常超前,已经给整个前端世界带来了冲击性的影响。它们包括:
- 组件和基于组件的设计流程;
- 单向数据流动;
- 虚拟DOM取代物理DOM作为操作对象;
- 用JSX语法取代HTML模板,在JavaScript里声明式地描述UI。
这几条简单的原则放在一起带来了大量的好处:
前端和后端都能够从React组件渲染页面,完全解决了SEO长期困扰JavaScript单页应用的问题;
我们可以简单直接地写前端测试而完全忘掉DOM依赖;
组件的封装方式和单向数据流动能够极大地简化前端架构的理解难度。
我们来看一个例子:
- varHelloMessage=React.createClass({
- render:function(){
- return<div>Hello{this.props.name}</div>;
- }
- });
- React.render(<HelloMessagename="John"/>,document.body);
这个React版的Hello World已经展现了React的一些核心特性。首先,HelloMessage是一个React组件;创建React应用的时候,我们总是以组件为出发点。每个组件的核心是一个render方法,在其中我们把这个组件的props和state拼装到一个最终要渲染的模板中,然后返回这个模板(确切地说这里是一个UI描述而不是传统意义上的模板)。这段代码里看起来像HTML一样的部分就是著名的JSX语法,它是在React中描述“模板”的最佳方式。
现在,以var开头的第一段里我们定义了一个叫HelloMessage的组件;下面的React.render这一行所做的,则是把这个组件渲染到document.body里——也就是我们实际的页面上。但在使用〈HelloMessage/〉的时候,我们做了另一件事:name="John"。看起来很像HTML中的元素属性,但是既然JSX不是HTML,这个语法的作用是什么呢?实际上,这就是我们向React组件传入props的方式。回头看第一段,我们可以看到在组件的内部有对this.props.name的引用。这个name就是我们刚刚指定的John!
看到这里,如果你熟悉jQuery的话也许在想,这与$(document.body).html('Hello John') 有什么根本区别呢?
这就是虚拟DOM出场的地方了。我们像写HTML一样写JSX,但是JSX并不会直接变成HTML和DOM。在幕后,React维护着一个虚拟DOM,而实际上被浏览器直接操作的“物理”DOM只是这个虚拟DOM的投影。虚拟DOM不依赖于浏览器环境,它可以运行在任何JavaScript执行环境。这就让下面的代码成为可能:
copy
varhtml=React.renderToString(<HelloMessagename="John"/>);res.send(html);
如果第二行有点眼熟,你没有猜错——这段代码发生在服务器端!是的,同样的 HelloMessage,我们不仅可以让React在前端渲染到页面,同样可以在后端直接渲染成HTML字符串,然后把它返回给前端。服务端预渲染就这么自然地发生了。
React带来的革命性创新是前端世界过去几年最激动人心的变化。自从接触React以来,我们深信React会彻底改变客户端开发者(包括前端、iOS和Android)的开发体验。在下面的篇幅里,我们想从四个大的方向——目标平台(Targets)、数据处理(Data)、工具(Tools)和新的挑战——分享一下React生态系统和社区的进展和未来趋势。
目标平台
对于虚拟DOM的讨论,很多人会说速度快过于真正的DOM。这样的讨论可以让人快速入门理解React,但是真正写过React应用的人会明白速度并不是虚拟DOM的精髓。我们认为虚拟DOM的存在帮助我们做到了两件事。第一是申明式UI。通过虚拟DOM,UI不再是一个不断被更变的DOM,你只要申明UI是怎么生成的,React会自动帮你把UI的改变渲染到真正的DOM上。这种新的思维方式让你可以不用手动操作真正的DOM。第二是多Target。我们一直在讲Web,但React让我们做到Web以外的Target。虚拟DOM更像是UI虚拟机,自动帮你映射到真正的实现上,可以是浏览器DOM、iOS UI、Android UI。甚至有人做到了React映射到终端文本UI。
多Targets是React社区常常在讨论的主要话题之一。多Targets的根本是提高开发者体验。开发者体验(DX,Developer Experience)是在React社区里屡次被提起的概念。如何在保持一样的用户体验下,提高开发者体验,是包括React在内的前端社区正在思考的问题。事实上任何一家有多客户端的公司都面临着这样同一个问题:在各种客户端语言里重新造轮子。开发者需要学习新的语言、写和维护类似的功能。提升客户端开发者体验就是减少学习成本和维护成本。这就是React提倡的“Learn once,write everywhere”。
最近也有一些鼓舞人心的消息。Facebook内部Ads Manager iOS版本由7位前端工程师用React Native花了5个月完成。而Android版本,是同一班人,3个月内完成。代码重用率达到了87%。
多Targets也可以是在单个平台更深度的结合。来自React核心团队的Sebastian Markbåge在ReactEurope大会上给了一个让人目瞪口呆的演讲《DOM as a Second-class Citizen》。演讲中他畅想React直接输出到浏览器架构的底层(图1浏览器的渲染架构,图2为Sebastian Markbåge认为React可以做的事情)。
图1 浏览器的渲染架构
图2 Sebastian Markbåge认为React还可以做很多事情
姑且不谈该不该这么做,通过虚拟DOM打开了这样的机会就已经让我们兴奋不已了。也说明了Facebook在设计React时已经考虑到超越DOM。想法确实很超前。
【服务端预渲染(Pre-rendering)】
对于其他主流前端框架,页面SEO和首次打开速度的问题都很让人头疼。Twitter当年因为首次打开速度过于慢甚至重回服务器渲染方案。一直以来人们一直在寻找一种只需要编写一次UI组件,前后端同时都能渲染的方案。如果能做到的话,我们就可以在首次打开页面时先用服务端渲染页面HTML,当浏览器收到后已经可以显示页面。这样SEO和首次打开速度都能被解决。这种完美方案社区里称之为Isomorphic/Universal App。
React原生支持了Pre-rendering(服务端渲染)。由于有虚拟DOM,也就意味着我们只需要后端运行JavaScript引擎就能渲染整个DOM。目前主流后端语言都可以运行V8 JavaScript引擎。比如Strikingly的后端使用Ruby on Rails,只需要使用开源的react-rails gem就可以在Rails后端渲染前端React组件。
使用服务端渲染时要注意window和document这些浏览器才有的全局变量是不存在的。React组件提供这两个lifecycle hook:componentDidMount和componentDidUpdate在服务器不会被运行,只有在前端才会运行。使用服务器渲染时如果要使用任何浏览器才有的变量需要把代码放到这两个lifecycle hook定义里。
数据处理
React定义自己为MVC中的View。这让前端开发者从V开始去思考UI设计。但现在针对数据操作和获取方式,社区里还没有一种公认的方法。这也是任何写React应用时最难处理的地方。
【Flux】
对于M和C,Facebook提出了Flux的概念。Flux是一个专门为React设计的应用程序架构:应用程序由Dispatcher、Store和View组成,其中的View就是我们的React组件。Flux的核心是如图3所示的单向数据流动。
图3 单向数据流动为Flux的核心
应用程序中的任何一次数据变化都作为Action发起,经过Dispatcher分发出去,被相关的Store接收到并整合,然后作为props和state提供给View(React组件)。当用户在View上做了任何与数据相关的交互,View会发起新的Action,开启一次新的数据变化周期。这种单向性使Flux在高层次上比传统MVC架构和以Angular和Knockout为代表的双向数据绑定容易理解得多,大大简化了开发者的思考和Debug过程。
在Facebook把Flux作为一种设计模式(而不是已经做好的框架)宣布之后,几乎每个月出现一新的Flux库,他们都有各自的特色,有的对服务器渲染支持比较好,有的运用了更多函数式编程的概念。很多Flux库更像是实验,这有助于React生态的生长,但不可否认的是,未来会有大量Flux库慢慢死去,而只有少数会存留下来或进行合并。
【GraphQL】
在构建大型前端应用时,前端和后端工程师通过API的方式进行合作。API也是双方的协议。现在主流的方式是RESTful API,然而在实践中,我们发现RESTful在一些真实生产环境的需求下不是很适用。往往我们需要构建自定义endpoint,而这违背了RESTful的设计理念。
举个例子,我们想要显示论坛帖子、作者和对应的留言。我们分别要发出三个不同的请求。第二个请求依赖第一个请求结果返回的user_id,前端需要写代码协调请求之间的依赖。分别发出三个不同请求在移动端这种网络不稳定的环境下效果很不理想。
copy