React生命周期深度完全解读

在 React 中,对于每一次由状态改变导致页面视图的改变,都会经历两个阶段:render 阶段commit 阶段

只有 class 组件才有生命周期,因为 class 组件会创建对应的实例,而函数组件不会。组件实例从被创建到被销毁的过程称为组件的生命周期

由 class 组件创建的实例具有生命周期,它的 render 函数在 render 阶段执行,并在此阶段进行 DOM 节点的 diff(diff 算法就是在此阶段进行的),找出需要改变的 DOM 操作。然后在 commit 阶段将对应的 DOM 操作提交至视图中。

而 class 组件实例的所有生命周期函数,都会在 render 阶段和 commit 阶段执行。

注:红色为 React 17 已经废弃的生命周期钩子,绿色为新增的生命周期钩子

在首次渲染页面时,会调用 Mount 相关生命周期钩子;在之后的页面渲染中,会调用 Update 相关生命周期钩子。所以与 Mount 相关的生命周期钩子只会被调用一次。

render 阶段

render 阶段会执行众多生命周期钩子,例如:在首次渲染时执行 constructor、getDerivedStateFromProps、componentWillMount、render,在更新时执行 componentWillReceiveProps、shouldComponentUpdate、componentWillUpdate、render,在渲染阶段捕捉到了后代组件中的错误时会执行 getDerivedStateFromError。

接下来,看看这些生命周期钩子的调用时机,以及它们的作用。

constructor

该方法只会执行一次,调用该方法会返回一个组件实例。

在初始化阶段执行,可直接对 this.state 赋值。其他生命周期函数中只能通过 this.setState 修改 state,不能直接为 this.state 赋值。

使用场景:

一般在 constructor 中做一些组件的初始化工作,例如:初始化组件的 state。

相关React实战视频讲解:进入学习

componentWillReceiveProps

在已挂载组件接收到新的 props 之前调用。你可以在这个函数中比较新旧 props,并根据新旧 props 更改 state。但是它会破坏 props 数据的单一数据源

在首次渲染组件时,不会调用此生命周期钩子;使用 this.setState 触发组件更新时,也不会调用此生命周期钩子。

不过要注意:如果是父组件渲染导致了组件的重新渲染,即使传给该组件的 props 没变,该组件中的这个生命周期函数也会被调用。

我们一般不使用此生命周期函数,因为它通常会破坏数据源的单一性。

getDerivedStateFromProps

它是一个静态方法,接收 props 和 state 两个参数。它会在调用 render 方法之前被调用,不管是在初始挂载时还是在后续组件更新时都会被调用。

它的调用时机和 componentWillMount、componentWillUpdate、componentWillReceiveProps 一样都是在 render 方法被调用之前,它可以作为 componentWillMount、componentWillUpdate 和 componentWillReceiveProps 的替代方案。

当然,它的作用不止如此,它可以返回一个对象,用来更新 state,就像它的名字一样,从 props 中获取衍生的 state。如果不需要更新 state 则可以返回 null。

需要注意的是:这个生命周期函数是类的静态方法,并不是原型中的方法,所以在其内部使用 this 访问到的不是组件实例。

此生命周期钩子不常用,如果可以的话,我们也尽可能不会使用它。

关于为什么要废弃 componentWillMount、componentWillUpdate、componentWillReceiveProps 三个生命周期钩子而新增 getDerivedStateFromProps 生命周期钩子,后面会说明原因。

shouldComponentUpdate

在组件准备更新之前调用,但是首次渲染或者使用 forceUpdate 函数时不会被调用。跟它的名字一样,它用来判断一个组件是否应该更新。

默认情况下,当组件的 props 或者 state 变化时,都会导致组件更新。它在 render 方法之前执行,如果它的返回值为 false,则不会更新组件,也不会执行后面的 render 方法。

它接收两个参数,nextProps 和 nextState,即下一次更新的 props 和下一次更新的 state。我们可以将 this.props 和 nextProps 比较,以及将 this.state 与 nextState 比较,并返回 false,让组件跳过更新。不过注意:它并不会阻止子组件因为 state 改变而导致的更新。

使用场景:

这个生命周期方法通常用来做性能优化。

componentWillMount(UNSAFE)

在组件挂载至 DOM 之前调用,并且只会调用一次。它在 render 方法之前调用,因此在 componentWillMount 中调用 this.setState 不会触发额外的渲染。

这个生命周期钩子使用频率较小,因为我们一般在 constructor 中初始化 state,在 componentDidMount 中引入副作用或者订阅内容

componentWillUpdate(UNSAFE)

在组件即将更新之前执行,如果 shouldComponentUpdate 函数返回 false,则不会调用 componentWillUpdate 方法。

这个生命周期钩子和 componentWillMount 类似,执行的时机是相同的,只不过 componentWillMount 在组件首次渲染时执行,而 componentWillUpdate 在组件后续更新时执行。这两个生命周期函数都不经常使用。

render

render 方法是类组件中唯一必须实现的方法,它的返回值将作为页面渲染的视图。render 函数应该为纯函数,也就是对于相同的 state 和 props,它总是返回相同的渲染结果。

render 函数被调用时,会返回以下四种类型之一:

  • React 元素:通常为 JSX 语法。例如:<div /><MyComponent> 等等。
  • 数组或者 fragments:render 方法可以通过数组返回多个元素。
  • Portals:渲染子节点至不同的子树中。
  • 字符串或者数值:会作为文本节点被渲染。
  • boolean 类型或者 null:什么都不渲染。

需要注意的是:如果 shouldComponentUpdate 生命周期钩子返回 false,则 render 方法(render 阶段后续生命周期钩子)不会执行。

commit 阶段

commit 阶段在首次渲染时会执行 componentDidMount,在组件更新时会执行 getSnapshotBeforeUpdate 和 componentDidUpdate。

componentDidMount

该生命周期方法会在组件挂载之后执行,也只会执行一次,也就是将组件对应的 DOM 插入 DOM 树中之后

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值