React入门学习

为了得到更好的阅读体验,请访问原地址:传送门html

1、React 简介

React 是什么

React 是一个起源于 Facebook 的内部项目,由于当时 Facebook 对于市场上全部的 JavaScript MVC 框架都不太满意,因此索性就本身写了一套,用来架设 Instagram。作出来以后,发现这套东西还蛮好用的,因而就在 2013 年 5 月开源了前端

在这里咱们须要稍微注意一下 库(Library)框架(Framework) 的区别,React 自己是一个用于构建用户界面的 JavaScript 库,而咱们平时所说的 React 框架实际上是指的是 React/ React-router 和 React-redux 的结合体,库和框架的本质区别体如今于控制权:react

  • 「库」是一个封装好的特定的集合,提供给开发者使用,并且是特定于某一方面的集合(方法和函数),库没有控制权,控制权彻底在于使用者自己;
  • 「框架」顾名思义是一套架构,会基于自身的特色向用户提供一套比较完整的解决方案,若是使用者选定了一套框架,那么就须要根据框架自己作出必定的适应。

为何使用 React?

这是一个很是有趣的问题,也让我困惑和苦恼。在笔者还在学校的时候尝试用 Vue 搭建了一套简单的博客系统,学习曲线平滑,让只会一些基础 HTML/ CSS 代码的我经过一段时间学习就可以上手了,可是学习 React 以来,进展变得相对缓慢.. 一部分缘由是由于 React 创新性的开发模式以及让我感到无所适从的 JSX 语法(菜才是原罪)。算法

Vue 做者尤雨溪在知乎上回答「Vue 和 React 的优势分别是什么?」这个问题的时候提到 :编程

这里我能够大方地认可,若是多年之后要论历史地位,React 确定是高于 Vue 的。事实上,我做为一个开发者,也是由衷地佩服 Jordan Walke, Sebastian Markbage 这样的,能从开发模式层面上提出突破性的新方向的人。redux

React 从一开始的定位就是提出 UI 开发的新思路。当年 Pete Hunt 最开始推广 React 的时候的一句口号就叫 "Rethinking Best Practices",这样的定位使得 React 打开了一些全新的思路,吸引了一群喜欢折腾的早期核心用户,并在这个基础上经过社区迭代孵化出了许多今天被 React 开发者看成常识的 pattern。这是 React 伟大的地方,Vue 里面也有不少地方是直接受到了 React 的启发。React 敢作这样的尝试,是由于它是 Facebook。这样的体量的公司,在 infrastructure 层面得到质的提高,收益是巨大的,并且 Facebook 的工程师们足够聪明又要靠工资吃饭,改变他/她们的习惯并非什么问题。而对外推广,则是一种大公司才有的 “改变业界” 的底气。浏览器

相比「为何使用 React?」的理由,称赞 React 的却是明显更多一些(React 确实是突破性的开发模式)。性能优化

是由于 React 组件化的思想吗?不是。我以为这跟多少跟微服务化之类的概念有点儿相似,这是属于一个时代对于计算机工程的思想进步,是对于团队协做提出的新一种成熟的解决方案,也是必然的一种趋势。当前流行的无论是 Angular/ Vue 仍是 React,都自然的支持着组件化的概念。babel

那是由于 React 性能出众吗?我想也不是。或许 React 刚出世时由于其独特高效的虚拟 DOM 设计,可以在前端江湖中平步青云,可是如今前端技术都主键地趋于成熟(我也不懂,我乱说的..),从不少地方的对比数据中,都可以看获得其实 React 与其余框架的性能差别并非特别大。而且体如今平时的开发中,这样对比不明显的速度差别,根本没有多大的用处。网络

还看到一种观点,说 React 适用于构建大型的项目。从我并很少的了解中,我知道 React 体系中自然有着许多的约束,以及一些不成文的约定,这就好像是 SpringBoot 中默认提供给使用者的一些姿式,自然就有很强的工程性,加上一些约定俗成的代码风格 or 归约,这就使得 Java 很适合一些大型的团队项目。但能不能开发大型的项目历来都是取决于人,而不是采用了哪一种框架。

因此比较令我信服的理由是(我乱猜的):像 Java 同样,React 体系足够成熟,社区也很是活跃,你遇到的问题很容易在网络上找到答案,而且也有一些成熟的实践 or 轮子用以解决各类各样的问题。并且 React 还有一个比较特别的特性是:你可以比较无痛地使用 React Native 开发原生移动应用。

2、React 核心概念

虚拟 DOM(Vitural Document Object Model)

要理解这个「虚拟 DOM」的概念,首先咱们就须要知道什么是「DOM」。咱们先暂时忘掉什么网页之类的,咱们想象如今咱们须要编写程序来对下列的 Markdown 文档进行改变应该怎么作:

# Title
## subtitle - 1
content - 1
## subtitle - 2
content - 2复制代码

好比我如今就想要 content - 2 的内容进行改变,那么我就须要一行一行的不断遍历直到最后遍历到它才能进行操做,对内容改变的操做都差很少,因此若是我想对这个查找的操做进行优化,最简单的想法就是把它树化以减小高度,增长效率。

DOM 的概念

DOM 是英文 Document Object Model 的缩写,即文档对象模型。它是一种跨平台的、独立于编程语言的 API,它把 HTML、XHTML 或 XML 文档都当作一个树结构,而每一个节点视为一个对象,这些对象能够被编程语言操做,进而改变文档的结构,映射到文档的显示。DOM 最开始的时候是和 JavaScript 交织在一块儿的,只是后来它们最终演变成了两个独立的实体。DOM 被设计成与特定编程语言相独立,尽管绝大部分时候咱们都是使用 JavaScript 来操做,但其实其余的语言同样能够(如 Python)。

假若有这么一段 HTML 代码:

<html>
  <head>
    <title>文档标题</title>
  </head>
  
  <body>
    <a href="">连接</a>
    <h1>标题</h1>
  </body>
</html>复制代码

那么它最终就应该会是下面这棵树同样的结构:

这里不对 DOM 节点的类型啊方法之类的进行讨论,咱们只须要对 DOM 有一个大体的概念就行了。

浏览器渲染 DOM 的流程

咱们能够简单了解一下浏览器渲染 DOM 的流程:

  1. 解析 HTML 创建 DOM 树;
  2. 解析 CSS,并结合 DOM 树造成 Reander 树;
  3. 布局 Render 树(Layout/ reflow),肯定各节点的尺寸、位置等信息;
  4. 绘制 Render 树(Paint),绘制页面像素信息;
  5. 浏览器将各层信息发给 GPU,GPU 会将各层合成(Composite),显示在屏幕上;

操做 DOM 为何慢

其实严格来讲,单纯的操做 DOM 并不慢,说它慢是带有必定条件的。

想象在一次事件循环中屡次操做 DOM 时,有时但愿 JS 代码中能马上获取最新的 DOM 节点信息,这时浏览器不得不挂起 JS 引擎,转而调用 DOM 引擎,计算渲染出最新的 DOM,以此来获取最新的 DOM 节点信息,接着再从新激活 JS 引擎 继续后续的操做。

能够预见,上述操做不只须要屡次进行引擎的切换,还须要屡次计算布局,从新绘制 DOM。事实上paint是一个耗时的过程,然而layout是一个更耗时的过程,咱们没法肯定layout必定是自上而下或是自下而上进行的,甚至一次layout会牵涉到整个文档布局的从新计算。

可是layout是确定没法避免的,因此咱们主要是要最小化layout的次数。

因此,下降引擎切换频率、减少 DOM 变动规模才是 DOM 性能优化方案的关键!

Virtual DOM 算法步骤

虚拟 DOM 正是解决了上述问题,它的本质就是用 JS 对象来模拟出咱们真实的 DOM 树,它的算法大体以下:

  1. 用 JavaScript 对象映射造成 DOM 树的结构,而后用这个树构建一个真正的 DOM 树,插到文档当中;
  2. 当状态变动的时候,从新构造一棵新的对象树,而后用新的树和旧的树进行比较(Diff 算法),记录两棵树差别;
  3. 把第二步中所记录的差别应用到步骤一所构建的真正的 DOM 树上,视图就更新。

虚拟 DOM 和真实 DOM 的区别

咱们由此能够对比出二者的不一样:

  1. 改变多个状态,影响多个节点布局时,只是频繁的修改了内存中的 JS 对象,而后一次性比较并修改真实 DOM 中须要改的部分,最后在真实 DOM 中进行排版与重绘,减小过多 DOM 节点排版与重绘损耗;
  2. 真实 DOM 频繁排版与重绘的效率是至关低的;
  3. 虚拟 DOM 有效下降大面积(真实 DOM 节点)的重绘与排版,由于最终与真实 DOM 比较差别,能够只渲染局部(同2);

使用虚拟DOM的损耗计算:

总损耗 = 虚拟DOM增删改 + (与Diff算法效率有关)真实DOM差别增删改 + (较少的节点)排版与重绘

直接使用真实DOM的损耗计算:

总损耗 = 真实DOM彻底增删改 + (可能较多的节点)排版与重绘

Diff 算法

虚拟 DOM 的核心在于 Diff,它自动帮你计算那些应该调整的,而后只修改应该被调整的区域,省下的不是运行速度这种 "小速度",而是开发速度/ 维护速度/ 逻辑简练程度等 "整体速度"。

但虚拟 DOM 快也是在相对条件下的,这里引用 @尤雨溪大大在知乎问题《网上都说操做真实 DOM 慢,但测试结果却比 React 更快,为何?》上回答的一句话吧:

不要天真地觉得 Virtual DOM 就是快,diff 不是免费的,batching 么 MVVM 也能作,并且最终 patch 的时候还不是要用原生 API。在我看来 Virtual DOM 真正的价值历来都不是性能,而是它 1) 为函数式的 UI 编程方式打开了大门;2) 能够渲染到 DOM 之外的 backend,好比 ReactNative。

Diff 大体能够分为三种类型:

  • Tree Diff: 新旧两棵 DOM 树,逐层对比的过程,就是 Tree Diff,当整颗DOM逐层对比完毕,则全部须要被按需更新的元素,必然可以找到;
  • Component Diff: 在进行 Tree Diff 的时候,每一层中,组件级别的对比,叫作 Component Diff:
    • 若是对比先后,组件的类型相同,则暂时认为此组件不须要被更新;
    • 若是对比先后,组件类型不一样,则须要移除旧组件,建立新组件,并追加到页面上;
  • Element Diff: 在进行组件对比的时候,若是两个组件类型相同,则须要进行元素级别的对比,这叫作 Element Diff;

3、Hello World

  • 引用自:http://www.ruanyifeng.com/blog/2015/03/react.html - 阮一峰 - React 入门实例教程

使用 React 的网页源码,结构大体以下(能够直接运行):

<!DOCTYPE html>
<html>
<head>
    <meta charset="UTF-8"/>
    <title>Hello React!</title>
    <script src="https://cdn.staticfile.org/react/16.4.0/umd/react.development.js"></script>
    <script src="https://cdn.staticfile.org/react-dom/16.4.0/umd/react-dom.development.js"></script>
    <script src="https://cdn.staticfile.org/babel-standalone/6.26.0/babel.min.js"></script>
</head>
<body>

<div id="example"></div>
<script type="text/babel">
    ReactDOM.render(
        <h1>Hello, world!</h1>,
        document.getElementById('example')
    );
</script>

</body>
</html>复制代码

上面代码有两个地方须要注意。首先,最后一个

相关文章
相关标签/搜索