React 生命周期详解

183 阅读4分钟

生命周期

1、挂载阶段

在组件的挂载阶段,会依次调用以下生命周期函数。

1.constructor(props)

  • 初始化组件
  • 不要忘了加super

2.static getDerivedStateFromProps(props,state)

  • 挂载阶段,获取当前的props和state,然后根据props来对state进行修改
  • 静态方法,内部不能使用this方法
  • 16.3新增
  • 必须有返回值,返回值是对state的修改
  • 组件初始时一定一定要定义state属性

3.componentWillMount

  • 代表组件即将要挂载
  • 16.3后不建议使用,在17.x中使用,建议写成UNSAFE_componentWillMount
  • 不能和 getDerivedStateFromProps(props,state) 同时使用 4.render
  • 更具return中的值生成虚拟DOM,然后提交给 ReactDOM 渲染真实的DOM 5.componentDidMount
  • 组件已经挂载完毕,虚拟DOM已经添加到真实DOM中

2、更新阶段

react 组件更新的生命周期函数有三种不同的过程:父组件引起的当前组件更新、当前组件自己更新、forceUpdate

  1. 父组件更新引起当前组件更新

    1. React 16.3 及以后 与之前有差异

    (1)React 16.3之前

    1. componentWillReceiveProps(nextProps)
      • 在父组件更新后子组件接受到新的 Props 时触发,注意该函数调用的是 this.props 结果还是更新前的props,如果需要使用更新后的props,需要调用参数中接收到的nextProps
    2. shouldComponentUpdate(nextProps,nextState)
      • 用于判断是否要进行组件的更新
      • props 和 state 还是更新前的数据,使用更新后的传参数获取
      • 必须有返回值,返回值为布尔值。 true 时,生命周期继续向下进行,组件继续更新。false 时,停止组件更新,不会调用后续的生命周期函数
    3. componentWillUpdate(nextProps,nextState)
      • 代表组件即将更新
      • props 和 state 的相关问题如上述
    4. render
      • 根据新的 props 和 state 生成虚拟 DOM,然后讲新的虚拟DOM和旧的虚拟DOM对比找出更新点,更新真实DOM
      • 这里的 props 和 state 是更新后的
    5. componentDidUpdate(prevProps,prevState)
      • 代表组件已经更新完毕,真实DOM已经完成重新渲染

      • 需要获取更新前的 props 和 state,可以通过参数接收

      • 处理副作用(请求):获取真实DOM节点、数据请求

    (2)React 16.3

    React 16.3 中用 getDerivedStateFromProps 方法替换掉了 componentWillReceiveProps。从 React 16.3 起,componentWillReceiveProps 和 componentWillUpdate 逐渐被弃用,到 React 17.x 中使用他们需要加前缀 UNSAFE_,并且使用了 getDerivedStateFromProps 方法后,这俩不会再被调用。

    1. static getDerivedStateFromProps(newProps,newState)
      • 在更新阶段,可以获取新的 props 和 state ,同样返回值是要对 state 做的修改
    2. shouldComponentUpdate
      • 判断组件是否更新
    3. render
      • 生成新的虚拟DOM
    4. getSnapshotBeforeUpdate(prevProps,prevState)
      • react 16.3 新增
      • 执行在 render 生成虚拟DOM之后,渲染真实DOM之前,用于获取渲染前的DOM快照
      • 这里的this.state 和 this.props 已经是新的了,需要获取更新前的可以通过参数接收
      • 必须要有返回值,返回值会传递给 componentDidUpdate
    5. componentDidUpdate(prevProps,prevState,snapshot)
      • 16.3 中,新增第3个参数snapshot,用于接收 getSnapshotBeforeUpdate 传递过来的信息

      • 处理副作用(请求):获取真实DOM节点、数据请求

  2. 组件自己更新

    组件自己更新即在组件内部调用了 setState,引起当前组件的更新。组件自己更新经历过三个版本:16.3 之前、16.3、16.4及以后

    1. React 16.3 之前 ,依次调用以下函数 :
      • shouldComponentUpdate
      • componentWillUpdate
      • render
      • componentDidUpdate
      • 可以看到,这里组件更新不再监听 props 变化,只监听 state 的修改
    2. React 16.3 中 ,由于生命周期函数有变化,组件自更新所调用的函数也跟着有变化,依次为:
      • shouldComponentUpdate
      • render
      • getSnapshotBeforeUpdate
      • componentDidUpdate
    3. React 16.4 及以后,官方调整把组件自更新和父组件更新带来的组件更新做了统一,顺序为:
      • static getDerivedStateFromProps

      • shouldComponentUpdate

      • render

      • getSnapshotBeforeUpdate

      • componentDidUpdate

  3. forceUpdate

    强制更新,当组件依赖的数据不是 state 时,数据改变了,此时此刻希望视图也进行改变可以使用 forceUpdate 方法。forceUpdate 方法会强制视图更新,不会调用 shouldComponentUpdate。

    import { Component } from 'react'
    
    let name = "name"
    class App extends Component {
      render() {
        return <div>
          <p>{name}</p>
          <button onClick={() => {
            name = "新名字";
            this.forceUpdate(); // 不调用不会更新
          }}></button>
        </div>
      }
    }
    
    export default App;
    

3、卸载阶段

组件卸载即把组件从 DOM 中删除。只有一个生命周期函数:componentWillUnmount ,用于监听组件即将卸载,通常用于在组件卸载时,删掉一些组件加在 全局 中的内容。

生命周期图谱地址:projects.wojtekmaj.pl/react-lifec…

16.3以前

16.3

16.4及以后

整理自《React 工程师修炼指南》