今天的 Web 应用程序除了外观比过去更好看以外,应用程序的架构和创建方式已经和过去有很大的不同。为突出这点,我们来看看如下的应用:
这是一个简单的商品目录浏览应用程序,它和这种类型的其它应用程序一样,通常包含一个主页、一个搜索结果页、一个详情页等等。
如果你几年前做过这种应用程序,可能会采用包含多个单页面的方式。页面流可能会像下面这样:
在多页设计方式下,对于大多数改变页面显示的行为,Web 应用会导航到一个完全不同的页面。用户会看到原页面被销毁,然后出来一个新页面,这种用户体验很不尽人意。这对如何维护应用程序的状态有很大影响。除了通过 cookie 和一些服务端机制来保存用户数据外,基本上就不用管别的了。生活是美好的。
今天,需要在单个页面之间导航的 Web 应用模式似乎过时了...可能,真的过时了:
现代的应用程序趋向于采用一种称为单页应用(SPA)的模式。这种模式下,我们不需要导航到不同的页面,甚至不需要重新加载一个页面。应用的不同视图被加载和卸载到同一页面上。
在单页应用模式下,上面的应用看起来应该是下面这样子:
当用户与应用程序交互时,我们用匹配用户行为的数据和 HTML 替换红色虚线区域的内容,从而带来更流式的体验。我们甚至可以用很多视觉技术让新内容很好地过渡,而这种很酷的技术以前只在移动设备或者桌面应用中才有。这类效果在多个页面中导航时几乎是不可能的。
如果以前你没有听说过单页应用,这一切听起来就有点不可理喻。但是你很可能不知不觉遇到过一些单页应用。如果曾经用过 Gmail、Facebook、Instagram、Twitter 等流行 Web 应用,那么你实际上就是在用单页应用。在所有这些应用中,内容是动态显示的,不需要刷新或者导航到不同的页面。
讲了这么多,搞得好像这些单页应用很复杂一样。事实上并非完全如此。现在 JavaScript 以及大量第三方框架和库都已经有了很大提升,创建单页应用从没有像现在这样简单过。但是,这并不意味着没有提升的空间。
在创建单页应用时,有时我们会遇到三个主要的问题:
在单页应用中,我们的大部分时间会花在保持数据与 UI 同步上。例如,如果用户加载新的内容,我们要显式清除搜索字段吗?是否让一个导航元素上的活动标签依然可见?哪个元素要在页面上保留,哪个应该销毁?
这些都是单页应用独有的问题。而在老式多页应用模式中,这从来就不是问题,因为在多页应用模式下在页面之间导航时,UI 中的一切都会被销毁,然后又重建起来。
DOM 操作很慢很慢。手动查询元素、添加子节点、删除子树、执行其它 DOM 操作,这些都是在浏览器中所做的最慢的事情。然而,不幸的是,在单页应用中,我们要做很多这种事情。要响应用户行为以及显示新内容,就不得不操作 DOM。
处理 HTML 模板会很痛苦。在单页应用中导航,实际上就是处理 HTML 文档片段。这些 HTML 文档片段用来表示要显示的内容,经常被称为模板。要处理模板,将内容在同一页面中显示出来,我们就得用 JavaScript 来操作模板,用数据来填充模板,这样代码很快变得很复杂。
更糟糕是,对于不同的框架,其模板的语法以及与数据交互的方式有很大不同。例如,如下是 Mustache 中的模板示例:
var view = {
title: "Joe",
calc: function () {
return 2 + 4;
}
};
var output = Mustache.render("{{title}} spends {{calc}}", view);
有时,你的模板可能看起来有点像干净的 HTML,你可以自豪地在同学面前炫耀。有时,你的模板可能是难以理解的,充满了设计用来帮助将 HTML 元素映射到某些数据的自定义标签。
尽管有这些缺点,单页应用程序并不是到处都是。单页应用只是目前的一部分,并且会彻底地构成未来web 应用创建的方式。这并不意味着我们不得不容忍这些缺点。为解决这。。。。
Facebook (和 Instagram) 觉得该解决这些问题了。在经历了足够的单页应用实践后,他们发布了一个叫做 React 的库。React 不仅解决了这些缺点,还改变了我们创建单页应用的思考方式。
在下面的小节中,我们来看看 React 带来的一些大事。
在单页应用中,跟踪 UI 并维护状态是很难,而且很耗时间。而在 React 中,你只需要关注一件事情:UI 所处的最终状态。它不关心 UI 开始是什么状态,也不关心用户改变 UI 会采取哪些步骤,只需要要关心 UI 结束的状态:
React 负责管理一切。它搞清楚要发生什么,才能确保 UI 被正确表示。所以,所有状态管理的事情不再需要我们操心。
因为 DOM 操作是真的很慢,所以我们永远不会直接用 React 修改 DOM,而是修改内存中的虚拟 DOM:
操作虚拟 DOM 非常快,当时机合适时,React 负责更新真实 DOM。它通过比较虚拟 DOM 和真实 DOM 之间的差别,查明哪个改变很重要,然后在一个称为 Reconciliation 的过程中作出最少量的 DOM 改变,以确保一切保持最新。
译者注:简单说, React在每次需要渲染时,会先比较当前DOM内容和待渲染内容的差异,然后再决定如何最优地更新DOM。这个过程被称为
reconciliation
。
React 鼓励我们将视觉元素分为更小的组件,而不是一整大块:
编程领域中,模块化、简洁、自包含是好的理念。React 把这些理念带到用户界面中。很多 React 的核心 API 围绕着更容易创建更小的界面组件,这些界面组件随后可以与其它界面组件组合,创建更大更复杂的界面组件,就像俄罗斯套娃一样:
这是 React 简化(以及改变)创建 Web 应用界面的主要方式之一。
虽然这听起来有点不可理喻,(我们知道,在 Web 标准年代,崇尚的是结构、表现形式和行为分离,也就是 UI 的结构、表现形式和行为部分分别分离到 HTML、CSS 和 JavaScript 三个文件中。完全在 JavaScript 中定义 UI,岂不是跟 Web 标准背道而驰么?)。但是且听我说完。如果像过去一样采用 HTML 模板的方式定义 UI,除了古怪的语法外,还有另一个主要问题。在模板中,除了只是显示数据,我们被限制做很多事情。例如,如果你想根据特定条件,选择显示哪一块 UI,就不得不在应用中到处写 JavaScript,或者用一些古怪的框架特有的模板语法,才能让它起作用。
例如,如下是 EmberJS 模板中条件语句的样子:
{{#if person}}
Welcome back, <b>{{person.firstName}} {{person.lastName}}</b>!
{{else}}
Please log in.
{{/if}}
而 React 实现的方式就很优雅。UI 完全在 JavaScript 中定义,我们可以利用 JavaScript 提供的强大功能在模板内做各种事情。我们受到的限制只是 JavaScript 支持不支持,而不是模板框架的限制。
现在,当我们思考完全用 JavaScript 定义 UI 时,可能会想到有些可怕的事情,比如引号、转义符、大量 createElement 调用等。不要担心。React 允许我们(可选)用 类似 HTML 的语法,即 JSX, 来定义 UI,而 JSX 是 JavaScript 完全支持的。我们可以像下面这样用 JSX 指定标记,而不是编写代码定义 UI:
ReactDOM.render(
<div>
<h1>Batman</h1>
<h1>Iron Man</h1>
<h1>Nicolas Cage</h1>
<h1>Mega Man</h1>
</div>,
destination
);
这段代码用 JavaScript 写看起来是这样的:
ReactDOM.render(React.createElement(
"div",
null,
React.createElement(
"h1",
null,
"Batman"
),
React.createElement(
"h1",
null,
"Iron Man"
),
React.createElement(
"h1",
null,
"Nicolas Cage"
),
React.createElement(
"h1",
null,
"Mega Man"
)
呀!通过使用 JSX,你就能使用很熟悉的 HTML 语法很轻松地定义 UI,同时依然拥有 JavaScript 的强大功能和灵活性。更佳的是,在 React 中,界面和 JavaScript 通常在一个地方。我们不再需要在定义一个界面组件的外观和行为的多个文件之间跳转了。This is templating done right.
到这里就快完了!React 并非一个完整的框架,它主要作用于视图层,所有它关心的问题围绕着界面元素,并且让界面元素保持最新。这意味着不管项目中所用的 MVC 架构中的 M 和 C 部分是什么,我们都可以自由用 React 作为 V 部分。这种灵活性让我们可以挑选熟悉的技术,并且让 React 不仅可以用来新创建 Web 应用,还可以用它来修改已有的应用,而不需要删除或者重构整个代码。
就新的 Web 框架和库而言,React 是相当成功。它不仅解决了开发者在创建单页应用程序时面临的常见问题,而且还加入了一些额外的技巧,让创建单页应用的界面变得相当相当简单。因为它是从 2013 年开始出现,所以 React 在很多流行网站和 app 中得到应用。除了 Facebook 和 Instagram 外,还包括 BBC、可汗学院、PayPal、Reddit、纽约时报、Yahoo 等等。
本文介绍 React 可以做什么以及为什么它可以这样做。在后面的教程中,我们将深入讲解本文中看到的所有东西,并且会涵盖可以帮助我们在项目中使用 React 的技术细节。
下一个教程: 创建你的一个 React 应用程序
译者注: 这是一套完整的 React 初学者教程,共十五篇。作者是供职于 Microsoft 的印度裔前端工程师kirupa。 已经全部翻译完成。大家感兴趣的话,我就慢慢都发出来。
扫码关注w3ctech微信公众号
共收到0条回复