react新旧版本生命周期函数详细介绍

2022-10-30 09:48:47

react生命周期主要分为三大类:挂载、更新、卸载

1.首先我们来看一下旧版本的react生命周期 <16.3版本

  1. 挂载

constructor、componentWillMount、componentDidMount

  1. 更新(更新可以分为两大类):

componentWillReceiveProp、shouldComponentUpdate、componentWillUpdate、componentDidUpdate

props变化触发的更新:
props变化 => componentWillReceiveProps(nextProps) => shouldComponentUpdate(nextProps, nextState)函数返回值如果是true => componentWillUpdate(nextProps, nextState) => render() => componentDidUpdate(prevProps, prevState)

state变化触发的更新:
state变化 => shouldComponentUpdate(nextProps, nextState)函数返回值如果是true => componentWillUpdate(nextProps, nextState) => render() => componentDidUpdate(prevProps, prevState)

由上可以看出:两种更新唯一的不同就是props触发的更新需要多走一个componentReceiveProps生命周期函数

3.卸载

componetWillUnmount()

下面附上旧版react生命周期示例图:

在这里插入图片描述

2.然后我们分析新版的react生命周期 >=16.3版本

**react 16.3出现了两个新的生命周期函数,并将逐渐废弃componentWillMount()、componentWillReceiveProps()、componentWillUpdate() **

首先我们来看看新版本react生命周期是如何运行的
  1. 挂载

constructor、getDerivedStateFromProps、componentDidMount

  1. 更新

getDerivedStateFromProps、shouldComponentUpdate、getSnapshotBeforeUpdate、componentDidUpdate

props、state变化 => getDerivedStateFromProps(nextProps, prevState) 返回值就是更新后的state => shouldComponentUpdate(nextProps, nextState)函数返回值如果是true => render() => getSnapshotBeforeUpdate(prevProps, prevState)参数与componentDidUpdate是一致的 => componentDidUpdate(prevProps, prevState, res) 其中res是getSnapshotBeforeUpdate的返回值

forceUpdate(强制更新)时,于上对比没有shouldComponentUpdate生命周期

  1. 卸载

componetWillUnmount

然后我们看看这两个新增的生命周期都有什么作用?

1.getDerivedStateFromProps(nextProps, prevState),代替componentWillReceiveProps()

根据方法名称我们也能大概知道这个生命周期是做什么的?让组件在 props 变化时更新 state

并且这个函数是static静态函数,我们都知道static中是访问不到this的,为什么这么做呢?

以前我们props变化时通过componentWillReceiveProps(nextProps)中的nextProps与当前组件this.props是否相同来更新state,然后再setState等等操作,但是这样的话就破坏了state的单向数据源,是你的组件变的更加不可预测,也增加了组件重绘次数,难以维护

而在新版本中,官方将更新 state 与触发回调重新分配到了 getDerivedStateFromProps 与 componentDidUpdate 中,使得组件整体的更新逻辑更为清晰。而且在 getDerivedStateFromProps 中还禁止了组件去访问 this.props,强制让开发者去比较 nextProps 与 prevState 中的值,以确保当开发者用到 getDerivedStateFromProps 这个生命周期函数时,就是在根据当前的 props 来更新组件的 state,而不是去做其他一些让组件自身状态变得更加不可预测的事情

需要注意的是:在方法中不能直接访问this,那么我们怎么设置state呢?此方法的返回值就是更新后的state

static getDerivedStateFromProps(nextProps, prevState) {
  if (nextProps.isLogin !== prevState.isLogin) {
    return {
      isLogin: nextProps.isLogin,
    };
  }
  return null;
}

2.getSnapshotBeforeUpdate(prevProps, prevState),代替componentWillUpdate()

getSnapshotBeforeUpdate() 在最近一次渲染输出(提交到 DOM 节点)之前调用。它使得组件能在发生更改之前从 DOM 中捕获一些信息(例如,滚动位置)。此生命周期的任何返回值将作为参数传递给 componentDidUpdate()

这两者的区别在于:

在 React 开启异步渲染模式后,在 render 阶段读取到的 DOM 元素状态并不总是和 commit 阶段相同,这就导致在
componentDidUpdate 中使用 componentWillUpdate 中读取到的 DOM
元素状态是不安全的,因为这时的值很有可能已经失效了。 getSnapshotBeforeUpdate 会在最终的 render
之前被调用,也就是说在 getSnapshotBeforeUpdate 中读取到的 DOM 元素状态是可以保证与
componentDidUpdate 中一致的。 此生命周期返回的任何值都将作为参数传递给componentDidUpdate()

下面附上新版react生命周期图解:
在这里插入图片描述

注意: 最常见的误解就是 getDerivedStateFromProps 和 componentWillReceiveProps 只会在
props “改变”时才会调用。实际上只要父级重新渲染时,这两个生命周期函数就会重新调用,不管 props 有没有“变化”

  • 作者:尼古拉斯二嘎
  • 原文链接:https://blog.csdn.net/qq_35629054/article/details/106668216
    更新时间:2022-10-30 09:48:47