俄罗斯贵宾会-俄罗斯贵宾会官网
做最好的网站

现代 js 框架存在的根本原因

现代 js 框架存在的根本原因

2018/06/05 · JavaScript · 1 评论 · 框架

原文出处: [Alberto

俄罗斯贵宾会,这篇文章主要是对知乎上关于react的讨论,做一些整理。观点都来自于网络上他人的说法。希望通过这些观点,可以形成自己的关于react的理解。

Gimeno](https://medium.com/dailyjs/the-deepest-reason-why-modern-javascript-frameworks-exist-933b86ebc445)   译文出处:[众成翻译

sea_ljf](https://zcfy.cc/article/the-deepest-reason-why-modern-javascript-frameworks-exist)   

俄罗斯贵宾会 1

我曾见过很多很多人盲目地使用(前端)框架,如 React,Angular 或 Vue等等。这些框架提供了许多有意思的东西,然而通常人们(自以为)使用框架是因为:

  • 它们支持组件化;
  • 它们有强大的社区支持;
  • 它们有很多(基于框架的)第三方库来解决问题;
  • 它们有很多(很好的)第三方组件;
  • 它们有浏览器扩展工具来帮助调试;
  • 它们适合做单页应用。

俄罗斯贵宾会 2

但这些都不是使用框架的根本原因。

最最本质的原因是:

俄罗斯贵宾会 3

(UI 与状态同步非常困难)


是的,就是这原因,让我们来看看为什么

假设你正在设计这样一个 Web 应用:用户可以通过群发电子邮件来邀请其他人(参加某活动)。UX/UI 设计师设计如下:(在用户填写任何邮箱地址之前,)有一个空白状态,并为此添加一些帮助信息;(当用户填写邮箱之后,)展示邮箱的地址,每个地址的右侧均有一个按钮用于删除对应的地址。

俄罗斯贵宾会 4

这个表单的状态,可以被设计为一个数组,里面包含若干对象,对象由邮箱地址和唯一标识组成。开始的时候,数组为空。当(用户)输入邮箱地址并按下回车键之后,往数组中添加一项并更新 UI。当用户点击删除按钮时,删除(数组中对应的)邮箱地址并更新 UI。你感觉到了吗?每当你改变状态时,你都需要更新 UI

(你可能会说:)那又怎样?好吧,让我们看看如何在不用框架的情况下实现它:

一个用来构建用户界面的 javascript 库

react是起源于facebook内部的项目,当时fb的前端团队对当时市面上所有的javascript mvc框架都不满意,决定自己写一套,用来架设Instagram。做出来之后,发现这套东西很好,于是在2013年5月开源了。


用原生(JS)实现相对复杂的 UI

以下代码很好地说明了使用原生 JavaScript 实现一个相对复杂的 UI 所需的工作量,使用像 jQuery 这样经典的库也需要差不多的工作量。

在这个例子中,HTML 负责创建静态页面,JavaScript 通过 document.createElement 动态改变(DOM 结构)。这引来了第一个问题:构建 UI 相关的 JavaScript 代码并不直观易读,我们将 UI 构建分为了两部分(译者注:应该是指 HTML与 JavaScript 两部分)。尽管我们使用了 innerHTML,可读性是增强了,但降低了(页面的)性能,同时可能存在 CSRF 漏洞。我们也可以使用模板引擎,但如果是大面积地修改 DOM,会面临两个问题:效率不高与需要重新绑定事件处理器。

但这也不是(不使用框架的)最大问题。最大的问题是每当状态发生改变时都要(手动)更新 UI。每次状态更新时,都需要很多代码来改变 UI。当添加电子邮件地址时,只需要两行代码来更新状态,但要十三行代码更新 UI。(此例中)我们已经让 UI (界面与逻辑)尽可能简单了!!

俄罗斯贵宾会 5

代码既难写又难理解,更麻烦的是它非常脆弱。假设我们需要(添加)同步服务器数据到邮件地址列表的功能,我们需要对比服务器返回结果与数组中数据的差异。这涉及对比所有数据的标识与内容,(当用户修改后,)可能需要在内存中保留一份标识相同但内容不同的数据。

为了高效地改变 DOM,我们需要编写大量点对点(译者注:指状态到 UI)的代码。但只要你犯下了很小的错误,UI 与状态将不再保持同步:(可能会出现)丢失或呈现错误的信息、不再响应用户的操作,更糟糕的是触发了错误的动作(如点了删除按钮后删除了非对应的一项)。

因此,保持 UI 与状态同步,需要编写大量乏味且非常脆弱的代码。

react产生过程

  1. 在写前端应用时,手动管理 DOM 和控件状态是没有规范化的操作,繁琐又容易出错。在大规模应用的情境下维护起来太困难。
  2. 既然在DOM手动管理太繁琐,那就在每次状态有更新的情况下重新渲染整个UI好了,这样可以省去一次次手动改变DOM的操作,也可以避免把组件状态存储在DOM当中的情况。
  3. 每次都重新渲染整个UI在很多时候会效率低下,所以就加上一个Virtual DOM来做different,把手动管理DOM的步骤隔离开来,把所有基本组件都变成JavaScript object。
  4. 既然在把所有的 HTML 组件都抽象化成js object了,也就不需要HTML为基础的模版了,应该直接写组件。Facebook在PHP已经使用XHP很久了,把那套方法搬到JavaScript上就成了JSX。
  5. UI的状态和获取的数据需要分开处理,使用state和props的概念来区分它们。

react的思想独特,性能出众,代码逻辑简单。

响应式 UI 拯救一切

俄罗斯贵宾会 6

所以,(之所以使用框架,)不是因为社区,不是因为工具,不是因为生态,不是因为第三方库……

目前为止,框架最大的改进是(为我们)提供了应用内部状态与 UI 同步的可靠保证。

只要你清楚特定框架的某些(特定)规则(如不可变状态),就差不多(可以正常使用)了。

我们只需要定义一次 UI 界面,不再需要为每个操作编写特定的 UI 代码,同时,每个相同的状态均有相同的输出(译者注:指 UI 一致):当状态改变后,框架自动更新(对应的)视图。

react的官方说明的理解

1.JUST THE UI. react可以认为只是一个模板引擎,使用在任何mv*(mvc,mvp,mvvvm等)的框架中做view层,使用react的组件化思想。
2.VIRTUAL DOM. 这是由react提出的概念,虚拟 DOM 会使得应用只关心数据和组件的执行结果,中间产生的DOM操作不需要应用干预。现在的很多前端框架都有开始使用虚拟DOM这个概念,可以提高js渲染的速度。
3.DATA FLOW. 单向数据流,只需要关心从数据怎么得出界面就行。由数据驱动页面的方式,可以轻松让用户界面和数据保持一致。当底层的数据变了,React 会自动处理所有用户界面的更新。可以让UI组件状态的维护管理更加清晰。

理解虚拟DOM:

虚拟 DOM 是在 DOM 的基础上建立了一个抽象层,我们对数据和状态所做的任何改动,都会被自动且高效的同步到虚拟 DOM,最后再批量同步到 DOM 中。

React 会在内存中维护一个虚拟 DOM 树,当我们对这个树进行读或写的时候,实际上是对虚拟 DOM 进行的。当数据变化时,然后 React 会自动更新虚拟 DOM,然后拿新的虚拟 DOM 和旧的虚拟 DOM 进行对比,找到有变更的部分,得出一个Patch,然后将这个 Patch 放到一个队列里,最终批量更新这些 Patch 到 DOM 中。


这样的机制可以保证即便是根节点数据的变化,最终表现在 DOM 上的修改也只是受这个数据影响的部分,可以保证非常高效的渲染。

理解单向数据流:

在jquery时代,我们都是基于事件驱动,对于简单的交互需求而言,这确实足够了,而且开发起来非常迅速。但业务一旦复杂,这种基于事件驱动的东西就会变得很乱,页面需要更新的DOM很多,就容易出错。

单向数据流的概念就出现了。更新 DOM 的数据总是从顶层流下来,用户事件不直接操作 DOM,而是操作顶层数据。这些数据从顶层流下来同时更新了DOM。你的代码就很少会直接处理DOM,而是只处理数据的变更。这样会很大程度上简化代码和逻辑。

举个例子:我点击一个button,然后页面上一个span里数字+1,原有的思考逻辑是“点击发生,然后数据变化,然后UI跟着变化+1”。而现在的思考逻辑是我的数据变化了,那么我的UI会自动更新,那么我只用考虑“点击发生,数据变化”。甚至可以把UI和数据变化分层然后处理。

本文由俄罗斯贵宾会发布于Web前端,转载请注明出处:现代 js 框架存在的根本原因

您可能还会对下面的文章感兴趣: