美文网首页
#渲染原理

#渲染原理

作者: Aaro_3835 | 来源:发表于2020-02-03 12:34 被阅读0次

    #渲染原理

    渲染:生成用于显示的对象,以及将这些对象形成真实的DOM对象

    - React元素:React Element,通过React.createElement创建(语法糖:JSX)

      - 例如:

      - ```

    标题

    ```

        - ``````

    - React节点:专门用于渲染UI界面的对象,React会通过React元素,创建React节点

    ReactDOM一定是通过React节点来进行渲染的

    - 节点类型:

      - React DOM节点:创建该节点的React元素类型是一个字符串

      - React 组件节点:创建该节点的React元素是一个函数或者是一个类

      - React TextNode(文本)节点: 有字符串、数字创建的

      - React 空节点:由null、undefined、false、true

      - React 数组节点:该节点由一个数组创建

    -真实DOM:通过document.createElement创建的元素

    ##首次渲染(新节渲染)

    1.通过参数的值创建节点

    2.根据不同的节点,做不同的事情

    1.文本节点:通过document.createTextNode创建真实的文本节点

    2.空节点:什么都不做

    3.数组节点:遍历数组,将数组每一项递归创建节点(回到第1步进行反复操作,知道遍历结束)

    4.DOM节点:通过document.createElement创建真实的DON对象,然后立即设置真实DOM元素的各种属性,然后遍历对应React元素的children属性,递归操作(回到第1步进行反复操作,知道遍历结束)

    5.组件即节点

    1.函数组件:调用函数(该函数必须返回一个可以生成节点的内容),将该函数的返回结果递归生成节点(回到第1步进行反复操作,知道遍历结束)

    2.类组件:

    1.创建类的实例

    2.立即调用对象的生命周期方法:static getDerivedStateFromProps

    3.运行对象的render方法,拿到节点对象(将该节点递归操作,回到第1步进行反复操作)

    4.将该组件的componentDidMount加入到执行队列(先进先出,先进先执行),档整个虚拟DOM树全部构建完毕,并且将真实的DOM对象加入到容器中后,执行该队列

    3.生成出虚拟dom树之后,将该树保存起来,一边后续使用,

    4.将之前生成的真实DOM对象,加入容器中

    虚拟DOM树

    ## 更新节点

    更新的场景:

    1. 重新调用ReactDom.render,触发根节点更新

    2. 在类组件的实例对象中调用setState,会导致该实例所在的节点更新

    **节点的更新**

    - 如果调用的是ReactDOM.render,进入根节点的**对比(diff)更新**

    - 如果你调用的setState

      - 1.运行生命周期函数,static getDerivedStateFromProps

      - 2.运行shouldComponentUpdate,如果该函数返回false,终止当前流程

      - 3.运行render,得到一个新的节点,进入改新的节点的**对比更新**

        - 4.将生命周期函数getSnapshotBeforeUpdate加入执行队列,以待将来执行

      - 5.将生命周期函数componentDidUpdate加入执行队列,以待将来执行

    后续步骤:

    1.更新虚拟DOM树

    2.完成真实的DOM更新

    3.依次调用执行队列中的componentDidMount

    4.依次调用执行队列中的getSnapshotBeforeUpdate

    5.依次调用执行队列中的componentDidUpdate

    6.依次调用执行队列中的componentWillMount

    **对比更新**

    将新产生的节点,对比之前虚拟DOM的节点,发现差异,完成更新

    问题:对比之前DOM树中哪个节点

    React为了提高对比效率,做出一下假设

    1.假设节点不会出现层次的移动(对比时,直接找到旧树中对应位置的节点进行对比)

    2.不同的节点类型会生成不同的结构

    1. 相同的节点类型:节点本身结构相同,如果是由React元素生成,type值必须一致

    2. 其他的,都属于不相同的节点类型

    3.多个兄弟通过唯一标识(key)来确定对比的新节点

    key值的作用:用于通过旧节点,寻找对应的新节点,如果某个旧节点有key值,则其更新时,会寻找相同层级中的相同key值的节点,进行对比。

    #### 找到了对比的目标

    判断节点类型是否一致

    - **一致**

    根据不同的节点类型,做不同的事情

    **空节点**:不做任何事情

    **DOM节点**:

    1.直接重用之前的真实DOM对象

    2.将其属性的变化记录下来,以待将来统一完成更新(现在不会真正的变化)

    3.遍历该新的React元素的子元素,**递归对比更新**

    **文本节点**:

    1.直接重用之前的真实DOM对象

    2.将新的文本变化记录下来,将来统一完成更新

    **组件节点**:重新调用函数,得到一个节点对象,进入**递归对比更新**

    **函数组件**:

    1.重用之前的实例

    2.调用生命周期方法getDerivedStateFromProps

    3.调用生命周期方法shouldComponentUpdate,若该方法返回false,终止

    4.运行render,得到新的节点对象,进入**递归对比更新**

    5.将该对象的getSnapshotBeforeUpdate加入队列

    6.将该对象的componentDidUpdate加入队列

    - **不一致**

    整体上,卸载旧的节点,全新创建新的节点

    **创建新节点**

    进入新节点的挂载流程

    **卸载旧节点**

    1.**文本节点、DOM节点、数组节点、空节点、函数数组节点**:直接放弃该节点,如果节点有子节点,递归卸载节点

    2.**类数组节点**:

    1.直接放弃该节点

    2.调用该节点的componentWillUnMount函数

    3.递归卸载子节点

    ### 没有找到对比的目标

    新的DOM树中有节点被添加

    新的DOM树中有节点被删除

    - 创建新加入的节点

    - 卸载多余的旧节点

    相关文章

      网友评论

          本文标题:#渲染原理

          本文链接:https://www.haomeiwen.com/subject/vvdfxhtx.html