# React渲染更新机制

# 【JSX原理剖析】

# 1】JSX转换本质

实际上,JSX 仅仅只是 React.createElement(component, props, ...children) 函数的语法糖

  • 所有的 JSX 最终都会被转换成React.createElement的函数被调用。

React.createElement源码如下:

在这里插入图片描述

# 2】虚拟DOM

  • React利用ReactElement对象组成了一个JavaScript的对象树;
  • JavaScript的对象树就是大名鼎鼎的虚拟DOM(Virtual DOM);
  • 整体的转换过程如下:

在这里插入图片描述

# 3】为什么采用虚拟DOM

为什么要采用虚拟DOM,而不是直接修改真实的DOM呢?

  • 很难跟踪状态发生的改变:原有的开发模式,我们很难跟踪到状态发生的改变,不方便针对我们应用程序进行调试;
  • 操作真实DOM性能较低:传统的开发模式会进行频繁的DOM操作,而这一的做法性能非常的低;
    • 首先,document.createElement本身创建出来的就是一个非常复杂的对象;
    • 其次,DOM操作会引起浏览器的回流和重绘,所以在开发中应该避免频繁的DOM操作;

虚拟DOM帮助我们从命令式编程转到了声明式编程的模式

React官方的说法:Virtual DOM 是一种编程理念

在这个理念中,UI以一种理想化或者说虚拟化的方式保存在内存中,并且它是一个相对简单的JavaScript对象,我们可以通过ReactDOM.render让 虚拟DOM真实DOM 同步起来,这个过程中叫做协调(Reconciliation);

这种编程的方式赋予了React声明式的API:你只需要告诉React希望让UI是什么状态,React来确保DOM和这些状态是匹配的。

你不需要直接进行DOM操作,只可以从手动更改DOM、属性操作、事件处理中解放出来;

# 【React更新机制】

React渲染流程:

在这里插入图片描述

React的更新流程:

在这里插入图片描述

React在props或state发生改变时,会调用React的render方法,会创建一颗不同的树

React需要基于这两颗不同的树之间的差别(diff算法)来判断如何有效的更新UI:

  • 如果一棵树参考另外一棵树进行完全比较更新,那么即使是最先进的算法,该算法的复杂程度为 O(n 3 ),其中 n 是树中元素的数量;
  • 如果在 React 中使用了该算法,那么展示 1000 个元素所需要执行的计算量将在十亿的量级范围;
  • 这个开销太过昂贵了,React的更新性能会变得非常低效;

于是,React对这个算法进行了优化,将其优化成了O(n),如何优化的呢?

  • 同层节点之间相互比较,不会垮节点比较;
  • 发现不同直接跳出比较。
  • 不同类型的节点,产生不同的树结构;
  • 开发中,可以通过key来指定哪些节点在不同的渲染下保持稳定;
Last Updated: 8/5/2020, 5:39:29 PM