react新旧生命周期对比

React16.3.0开始,生命周期进行了一些变化。本文主要介绍React16.3.0以后的生命周期。react

React16.3.0以前生命周期:

16版本以前的react组件的生命周期相信你们已经很熟悉。16版本的react对组件的生命周期函数进行了一些修改,下面进行详细说明。segmentfault

React16.3.0以前生命周期

建立期:
  1. constructor(props, context)
  2. componentWillMount()
  3. render()
  4. componentDidMount()
运行时:

props发生变化时bash

  1. componentWillReceiveProps(nextProps, nextContext)
  2. shouldComponentUpdate(nextProps, nextState, nextContext)
  3. componentWillUpdate(nextProps, nextState, nextContext)
  4. render
  5. componentDidUpdate(prevProps, prevState, snapshot)

state发生变化时网络

  1. shouldComponentUpdate(nextProps, nextState, nextContext)
  2. componentWillUpdate(nextProps, nextState, nextContext)
  3. render
  4. componentDidUpdate(prevProps, prevState, snapshot)
卸载时

componentWillUnmount()app

React16.3.0以后的生命周期

建立期:
  1. constructor(props, context)
  2. static getDerivedStateFromProps(props, status)
  3. render()
  4. componentDidMount()

或者以下生命周期:dom

  1. constructor(props, context)
  2. componentWillMount() / UNSAFE_componentWillMount()
  3. render()
  4. componentDidMount()

注意: getDerivedStateFromProps/getSnapshotBeforeUpdate 和 componentWillMount/componentWillReceiveProps/componentWillUpdate 若是同时存在,React会在控制台给出警告信息,且仅执行 getDerivedStateFromProps/getSnapshotBeforeUpdate 【React@16.7.0】函数

运行时:

props发生变化时性能

  1. static getDerivedStateFromProps(props, status)
  2. shouldComponentUpdate(nextProps, nextState, nextContext)
  3. render
  4. getSnapshotBeforeUpdate(prevProps, prevState)
  5. componentDidUpdate(prevProps, prevState, snapshot)

或者以下生命周期:fetch

  1. componentWillReceiveProps(nextProps, nextContext)/UNSAFE_componentWillReceiveProps
  2. shouldComponentUpdate(nextProps, nextState, nextContext)
  3. componentWillUpdate(nextProps, nextState, nextContext)
  4. render
  5. componentDidUpdate(prevProps, prevState, snapshot)

state发生变化时优化

  1. static getDerivedStateFromProps(props, status)
  2. shouldComponentUpdate(nextProps, nextState, nextContext)
  3. render
  4. getSnapshotBeforeUpdate(prevProps, prevState)
  5. componentDidUpdate(prevProps, prevState, snapshot)

或者以下生命周期:

  1. shouldComponentUpdate(nextProps, nextState, nextContext)
  2. componentWillUpdate(nextProps, nextState, nextContext)/UNSAFE_componentWillUpdate
  3. render
  4. componentDidUpdate(prevProps, prevState, snapshot)
销毁时

componentWillUnmount()

新的生命周期图示:

clipboard.png

生命周期详解

1.constructor(props, context)

constructor生命周期,如不须要,可缺省。一般会在 constructor 方法中初始化 state 和绑定事件处理程序。
可是,若是写了constructor,那么必须在其中调用super(props);不然可能会引发报错。

如:

class Base extends Component {
    constructor(props) {
        super();  //应该为 super(props);
    }
    state = {
        name: this.props.name
    }
    //....code
}
复制代码

抛出异常: Uncaught TypeError: Cannot read property 'name' of undefined.

一样,若是定义了context,在state中须要使用this.context去获取context上的内容,则须要super(props, context);

不过,若是你缺省constructor,那么在state中,能够放心的使用 this.props 或者是 this.context,不会引发报错。

class Base extends Component {
    state = {
        name: this.props.name,
        color: this.context.color
    }
    //....code
}复制代码

初始化的state一样能够在constructor中定义。若是须要给方法绑定this,那么统一在constructor中进行。

2.static getDerivedStateFromProps(props, state)

当组件的state须要根据props来改变的时候可调用此方法。这个方法是在 render() 前会被执行,每次触发render前,都会触发此方法。

该方法有两个参数props和state; 返回值为state对象, 不须要返回总体state,把须要改变的state返回便可。若是不须要,能够返回null.

class Base extends Component {
    state = {
        age: 20
    }
    static getDerivedStateFromProps(props, state) {
        return {
            age: 50
        }
    }
    render() {
        // 50
        return (
            <div>{this.state.age}</div>
        )
    }
}复制代码

这个方法容许组件基于 props 的变动来更新其内部状态,以这种方式得到的组件状态被称为派生状态。应该谨慎使用派生状态,可能会引入潜在的错误

3.render

React组件中必需要提供的方法。当state或者props任一数据有更新时都会执行。

render() 是一个纯函数,所以,不要在其中执行setState诸如此类的操做。render必须有一个返回值,返回的数据类型能够有:

  • null、String、Number、Array、Boolean。
  • React elements
  • Fragment
  • Portal

注意不要在render中调用setState

4.componentDidMount

componentDidMount()方法是在组件加载完后当即执行,也就是当该组件相关的dom节点插入到dom树中时。该方法在组件生命中只执行一次。
通常状况,咱们会在这里setState(),或者进行接口请求,设置订阅等。

class Base extends Component {
    state = {
        age: 20
    }
    componentDidMount() {
        this.fetchDate();
    }
    render() {
        return (
            <div>{this.state.age}</div>
        )
    }
    //other code
}复制代码

5.shouldComponentUpdate(nextProps, nextState, nextContext)

在渲染新的props或state前,shouldComponentUpdate被调用,默认返回true。forceUpdate()时不会调用此方法。

若是shouldComponentUpdate()返回false,那么getSnapshotBeforeUpdate,render和componentDidUpdate不会被调用。

今生命周期主要用于优化性能。

6.getSnapshotBeforeUpdate(prevProps, prevState)

在render()的输出被渲染到DOM以前被调用。使组件可以在它们被更改以前捕获当前值(如滚动位置)。这个生命周期返回的任何值都将做为第三个参数传递给componentDidUpdate().

7.componentDidUpdate(prevProps, prevState, snapshot)

在更新发生后调用 componentDidUpdate()。当组件更新时,将此做为一个机会来操做DOM。如将当前的props与之前的props进行比较(例如,若是props没有改变,则可能不须要网络请求。

若是组件使用 getSnapshotBeforeUpdate(),则它返回的值将做为第三个“快照”参数传递给 componentDidUpdate()。不然,这个参数是undefined。

8.componentWillUnmount()

在组件被卸载并销毁以前当即被调用。在此方法中执行任何须要的清理,例如使定时器无效,取消网络请求或清理在componentDidMount()中建立的任何监听。

最后,说明一点:

componentWillUpdate,componentWillReceiveProps,componentWillUpdate这三个生命周期在React将来版本中会被废弃。

而UNSAFE_componentWillUpdate,UNSAFE_componentWillReceiveProps,UNSAFE_componentWillUpdate 将来版本中仍可继续使用。

初始化阶段(父组件和子组件):

clipboard.png

运行阶段:父组件props/state更新

子组件的shouldComponentUpdate返回false,则子组件其后的生命周期都不在进行,可是父组件的生命周期继续执行。

clipboard.png

卸载阶段: 卸载父组件

clipboard.png

参考:

  1. segmentfault.com/a/11...
  2. www.jianshu.com/p/514...
  3. blog.csdn.net/qq_2931...
相关文章
相关标签/搜索