ReactReact全家桶React 生命周期+虚拟DOM+Diff算法

Posted 前端More

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了ReactReact全家桶React 生命周期+虚拟DOM+Diff算法相关的知识,希望对你有一定的参考价值。

文章目录

1 React 生命周期

React的生命周期:React实例从被创建到被销毁的过程,React组件中包含一系列勾子函数(生命周期回调函数), 会在特定的时刻调用。

只有 class 组件才有生命周期,因为 class 组件会创建对应的实例,而函数组件不会 。

React 生命周期主要包括三个阶段:初始化(挂载)阶段,更新阶段,销毁(卸载)阶段

1.1 初始化阶段

ReactDOM.render()触发初次渲染

  1. constructor():类组件中的构造函数
  2. static getDerivedStateFromProps(props, state) :从props得到一个派生的状态【新增】
  3. render():挂载组件
  4. componentDidMount():组件挂载完成

1.2 更新阶段

由组件内部this.setSate()或父组件重新render触发或强制更新forceUpdate()

  1. getDerivedStateFromProps(): 从props得到一个派生的状态 【新增】
  2. shouldComponentUpdate() : 组件是否应该被更新(默认返回true
  3. render(): 挂载组件
  4. getSnapshotBeforeUpdate():在更新之前获取快照【新增】
  5. componentDidUpdate(prevProps, prevState, snapshotValue):组件完成更新

1.3 卸载阶段

ReactDOM.unmountComponentAtNode()触发

  1. componentWillUnmount() :组件即将卸载

1.4 重要的勾子

  1. render:初始化渲染或更新渲染调用
  2. componentDidMount:开启监听, 发送ajax请求
  3. componentWillUnmount:做一些收尾工作, 如: 清理定时器

1.5 已经废弃的勾子

  1. componentWillMount
  2. componentWillReceiveProps
  3. componentWillUpdate

使用会出现警告,在React 18.0需要加上UNSAFE_前缀才能使用,以后可能会被彻底废弃,不建议使用。

2 虚拟DOM、Diff算法

2.1 原生JS和React渲染页面的区别

原生JS渲染页面:数据 => 真实DOM

React渲染页面:数据 => 虚拟DOM(内存中的数据)=> 真实DOM

优点:减少了DOM操作,减少了回流与重绘,保证性能的下限,比正常的DOM性能更好

缺点:首次渲染DOM时,由于多了一层虚拟DOM的计算,会比innerhtml插入慢。

2.2 虚拟DOM

虚拟DOM是JS按DOM(真实DOM)的结构来创建的虚拟树型结构对象,是对DOM的抽象,比DOM更加轻量型(属性更少), 只保留了真实 DOM 节点的一些基本属性,和节点之间的层次关系, 本质还是Object类型的对象,虚拟DOM最终会被React转化为真实DOM,呈现在页面上。 虚拟DOM会通过ReactDOM.render进行渲染成真实DOM。

2.3 Diff算法

Diff算法原理图

React 通过Diff算法只更新它需要更新的部分,React DOM 会将元素和它的子元素与它们之前的状态进行比较,并只会进行必要的更新来使 DOM 达到预期的状态。

Key 是虚拟DOM对象的标识,主要用在Diff算法中,每个虚拟节点都有一个唯一标识Key,通过对比新旧节点的key来判断节点是否改变,可以大大提高渲染效率。

Diff算法是用于比较新旧虚拟节点之间差异的一种算法,每个虚拟节点都有一个唯一标识key,通过对比新旧节点的key来判断节点是否改变,将两个节点不同的地方存储在patch对象中,最后利用patch记录的消息局部更新DOM。 比较规则如下 :

  • 旧虚拟DOM中找到了与新虚拟DOM相同的key:

    • 若虚拟DOM中内容没变, 直接使用之前的真实DOM
    • 若虚拟DOM中内容变了, 则生成新的真实DOM,随后替换掉页面中之前的真实DOM
  • 旧虚拟DOM中未找到与新虚拟DOM相同的key:

    • ​ 根据数据创建新的真实DOM,随后渲染到到页面

用index作为key可能会引发的问题:

  • 若对数据进行:逆序添加、逆序删除等破坏顺序操作,会产生没有必要的真实DOM更新 ==> 界面效果没问题, 但效率低
  • 如果结构中包含输入类的DOM,会产生错误DOM更新 ==> 界面有问题
  • 仅用于渲染列表用于展示,使用index作为key是没有问题的

开发中如何选择key?

  • 最好使用每条数据的唯一标识作为key, 比如id、手机号、身份证号、学号等唯一值
  • 如果确定只是简单的展示数据,用index也是可以的

由下图可知,第一次有三项数据渲染为真实DOM,第二次渲染中的数据比第一次多了一项,此时React使用Diff算法按照规则在虚拟DOM中依次对比每一项数据,发现前三项数据key和内容都相同,则复用第一次的真实DOM,最后一项数据没有则需渲染新数据为真实DOM,提高了渲染效率。

以上是关于ReactReact全家桶React 生命周期+虚拟DOM+Diff算法的主要内容,如果未能解决你的问题,请参考以下文章

React全家桶React生命周期

react全家桶生命周期

ReactReact全家桶React脚手架

ReactReact全家桶React Hooks

ReactReact全家桶React Hooks

ReactReact全家桶React脚手架