最近在家开始学习react,发现react的生命周期函数相比于Vue要“麻烦”的多,由于我学习React是买书看的,所以就有一定的延时性,书上的React版本还停留在16.1,通过网上查找发现从16.4之后就新增修改了几个钩子函数。所以就想写一篇关于react的钩子函数,加深下记忆和学习。

首先看下React16.4之后的生命周期函数

React16.4废弃的三个生命钩子函数

  • componentWillMount:这个方法在组件被挂在到DOM前调用,且只会被调用一次。
  • componentWillReceiveProps:这个方法在props引起的组件更新过程中,才会被调用。State引起的组件更新并不会触发该方法执行。
  • componentWillUpdate:这个方法在组件render调用前执行,可以作为组件更新前来执行某些事件。

取而代之的值两个新的生命周期函数

  • static getDerivedStateFromProps
  • getSnapshotBeforeUpdate

通常组件的生命周期可以分为三个阶段,分别是:

  • 挂载阶段
  • 更新阶段
  • 卸载阶段

挂载阶段

挂载阶段,可以理解为组件的初始化。通俗的说就是讲组件插入DOM中,只会发生一次。依次调用的生命周期方法有:

  • constructor
  • getDerivedStateFromProps
  • componentWillMount
  • render
  • componentDidMount

constructor

ES6 class的构造方法,组件被创建时,会首先调用组件的构造方法。这个构造方法接受一个props参数,props是从父组件中传入的属性对象,如果父组件中没有传入属性而组件自身定义了默认属性,那么这个props指向的就是组件的默认属性。我们必须在这个方法中首先调用super(props)才能保证props传入到组建中。
在构造函数中一般只做两件事

  • 初始化state对象
  • 绑定事件方法
    constructor(props){
      super(props)
      this.state = {
          name:'zs'
      }
      this.handleClick = this.handleClick.bind(this)
    }

    getDerivedStateFromProps

    static getDerivedStateFromProps(nextProps, prevState)

首先这个生命周期函数替代了componentWillReceiveProps,由于这是一个静态方法,所以不能在这个函数里面使用this。这个函数分别有两个参数:props和state。分别指接收到新的参数和当前state对象,函数会返回一个新的对象用来更新当前的state。如果不需要更新则返回null。

当我们接收到新的属性想要修改自身state的时候,就可以使用getDerivedStateFromProps

 class getMyName extends React.Component {
     state = {
         name:'zs'
     }
     static getDerivedStateFromProps(nextProps,prevState){
         if(nextProps.name !== prevState.name){
             return {
                 name:nextProps.name
             }
         }
         return null
     }
 }

componentWillMount

这个方法在组件挂载到DOM前调用,且只会被调用一次。这个方法中调用this.setState不会引起组件重新渲染。不过这个方法将在React17之后被移除,getDerivedStateFromProps将会代替它

render

这是React定义组件时唯一必要的方法

返回的类型有以下几种:

  • 原生的DOM
  • React组件
  • Fragment(片段)
  • Portals(插槽)
  • 字符串和数字
  • Boolean和null(什么都不会渲染)

这里面需要注意的是Render是一个纯函数,在这个方法中不能执行任何有副作用的操作,所以不能在render中调用this.setState。

componentDidMount

这个方法在组件被挂载到DOM后调用,且只会被调用一次。此时可以获取操作到真实DOM节点。同时还可以在这个函数中进行服务器请求,在这个方法中调用this.setState会引起组件重新渲染。

 componentDidMount(){
     this.$http.post('XXX',{XXX:XXX}).then(res=>{
        //todo something
     })
 }

更新阶段

当组件被挂载到DOM上,组件的props或state发生改变可以引起组件更新。组件更新阶段,依次调用的生命周期方法有如下几种:

  • componentWillReceiveProps
  • getDerivedStateFromProps
  • shouldComponentUpdate
  • componentWillUpdate
  • render
  • getSnapshotBeforeUpdate
  • componentDidUpdate

componentReceiveProps(nextProps)

这个方法只有在props引起的组件更新过程中才会被调用,State引起的组件更新并不会触发该方法执行。方法的nextProps参数是父组件传递给当前组件的新的props。同样react17之后将会移除该生命周期函数。

getDerivedStateFromProps

只要是更新都会调用该函数

shouldComponentUpdate(nextProps,nextState)

这个方法决定组件是否继续执行更新,这个方法返回一个布尔值,当返回true的时候(默认返回值),组件会继续执行更新过程。当方法为false的时候,组件的则不会再更新。一般通过比较nextProps、nextState和组件当前的props、state决定这个方法的返回结果。

shouldComponentUpdate(newProps, newState) {
    if (newProps.number < 5) return true;
    return false
}

componentWillUpdate

这个方法在组件render调用前执行,即状态改变后将在重新渲染前做的一些工作。

render

更新阶段触发

getSnapshotBeforeUpdate(prevProps,prevState)

该方法在render调用之后,componentDidUpdate之前调用。两个参数分别代表之前的属性和之前的state,该函数还有一个返回值会作为第三个参数传给componentDidUpdate(如果不想传值的话就返回null,否则控制台会警告)

componentDidUpdate(prevProps, prevState, snapshot)

该方法在getSnapshotBeforeUpdate方法之后被调用,有三个参数prevProps,prevState,snapshot,表示之前的props,之前的state,和snapshot。第三个参数是getSnapshotBeforeUpdate返回的

卸载阶段

组件从DOM中被卸载的过程,这个过程 只有一个生命周期函数。

componentWillUnmount

这个方法在组建被渲染前调用,可以在这里执行一些清理工作。比如清除组建中使用的定时器等。