react-节点更新与销毁

更新与销毁

发生更新的场景:

  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、getSnapshotBeforeUpdate、componentDidUpdate

componentDidMount来源于新子代类组件的挂载

对比更新

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

react为了提高对比效率,做出以下假设:

  • 假设节点不会出现层次的移动

    层次的移动就是比如原来A组件在第三层第一位,不会突然跑到第二层去
    对比的时候,react会直接找到旧树中该节点所在的对应位置进行对比

对比的方式:

  1. 不同的节点类型会生成不同的解构

    名词解释
    相同的节点类型: 节点本身类型相同(不管属性,虚拟DOM树更新前后节点都为div则相同,前为div后为p则不相同),如果是react元素则要求type值必须一致
    不同的节点类型: 非相同节点类型

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

    key值的作用: 用于通过旧节点,寻找对应的新节点,如果某个旧节点由key值,则其更新时,会在相同层级中找相同的key值进行对比
    key值应该在一个范围内(兄弟节点中)唯一,并且应该保持稳定(不要使用随机数之类的)

react依靠假设进行寻找,产生两种情况(找到与未找到)

找到了对比目标

如果找到了对比目标, 则进行节点类型判断

  • 节点类型一致
    根据不同的节点类型做不同的事情
    - 空节点: 不做任何事
    - DOM节点
    1. 直接重用之前的真实DOM对象
    2. 对比属性,将变动的属性记录下来,以待将来统一更新(现在不会发生变化)
    将来是啥时候? 往上看有个后续步骤,看到真实DOM更新了吗? 那就是将来
    3. 遍历该新React元素的子元素,进行递归对比更新
    递归对比更新: 说白了就是拿子元素重新走一遍更新流程
    - 文本节点
    a. 重用之前的真实DOM对象
    b. 将新的文本变化记录下来,将来完成更新
    - 组件节点: 分为函数组件与类组件
    - 函数组件: 重新调用函数,得到一个新的节点对象,进行递归对比更新
    - 类组件:
    1. 重用之前的实例,
    2. 调用生命周期方法 static getDerivedStateFromProps
    3. 调用生命周期方法shouldComponentUpdate, 若该方法返回false,则终止
    4. 运行render,得到新的节点对象,进行递归对比更新
    5. 生命周期函数getSnapshotBeforeUpdate加入执行队列
    6. 生命周期函数componentDidUpdate加入执行队列
    - 数组节点: 遍历数组, 进行递归对比更新

  • 节点类型不一致
    创建新节点 : 进入新节点挂载流程(首次渲染)
    卸载旧节点:
    1. 文本节点、DOM节点、数组节点、空节点、函数组件节点: 直接放弃该节点,如果节点有子节点,递归卸载节点
    2. 类组件节点
    - 直接放弃该节点
    - 调用该节点的componentWillUnMount函数
    - 递归卸载子节点

没有找到对比目标
  • 创建新加入的节点
  • 卸载多余的节点
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

合法的咸鱼

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值