React 的生命周期变化

React 从 v16.3 开始,对生命周期进行了渐进式的调整。废弃了一些生命周期方法和添加了一些新的生命周期方法。html

原生命周期

原生命周期图

新的生命周期

新的生命周期图

React 逐渐废弃的生命周期方法

  • componentWillMount
  • componentWillReceiveProps
  • componentWillUpdate

虽然废弃了这几个生命周期方法,可是 React 为了遵循版本兼容,因此 v16.3 并无删除这三个方法,而且还增长了UNSAFE_componentWillMount,UNSAFE_componentWillReceivePropsUNSAFE_componentWillUpdate方法,在 v16.3 版本中 新旧这几个方法均可以使用。 在 v16.3 之后的 v16.x版本中,新旧的方法依旧均可以使用,可是使用不带UNSAFE_前缀的方法,将提示被弃用的警告。 在v17 将删除componentWillMountcomponentWillReceivePropscomponentWillUpdate,只有带有UNSAFE_前缀新的生命周期方法可使用。react

React 新添加的生命周期方法

  • getDerivedStateFromProps
  • getSnapshotBeforeUpdate

组件的生命周期分为:挂载、更新、卸载。ajax

挂载

组件建立实例并插入 DOM 时,按照下面的生命周期方法顺序调用数组

  • constructor()
  • static getDerivedStateFromProps()
  • componentWillMount()/UNSAFE_componentWillMount() 将被弃用
  • render()
  • componentDidMount()

在有定义static getDerivedStateFromProps()componentWillMount()/UNSAFE_componentWillMount()将无效。服务器

constructor()网络

constructor(props)
复制代码

React 组件在挂载前,会调用它的构造函数,在构造函数内部必须执行一次super(props)。不能再constructor内部调用this.setState。 一般用于:函数

  • 经过给this.state初始化内部状态
  • 为事件处理函数绑定this

static getDerivedStateFromProps()性能

static getDerivedStateFromProps(newProps,prevState)
复制代码

是一个静态方法,父组件传入的newProps和当前组件的prevState进行比较,判断时候须要更新state,返回值对象用做更新state,若是不须要则返回nullui

render()方法以前调用,而且在初始挂载和后续更新时调用。this

import * as React from "react";
class App extends React.Component{
	constructor(props){
		super(props);
		this.state={
			childDown:1,
			num:0
		}
	}
	static getDerivedStateFromProps(props,state){
	    if(props.isDown === state.childDown){
	        return {
	            num:state.childDown
	        }
	    }
	    return null 
	}
	render(){
        return(
            <div>22</div>
        )
    }
}
复制代码

componentWillMount()/UNSAFE_componentWillMount() 弃用 在挂载以前调用。在render()以前调用。在此方法中调用setState不会触发render

有的习惯把请求放在此阶段中,但更推荐放在componentMidMount()中。 在服务器渲染时,在此方法中同步数据,但建议使用constructor来初始化数据。

render()

render()是组件中惟一必须实现的方法。

react()是做为渲染用的,能够返回如下类型

  • React 元素
  • 数组或fragments
  • Portals
  • 字符串或者数值类型
  • 布尔类型或null

render() 函数应该是纯函数。不可以调用setState

componentDidMount()

组件加载完成,可以获取真是的 DOM 在此阶段能够ajax请求绑定事件,在此阶段绑定了时间要在componentWillUnmount()取消。在此阶段能够调用setState,触发render渲染,但会影响性能。

更新

  • componentWillReceiveProps()/UNSAFE_componentWillReceiveProps() 弃用
  • static getDerivedStateFromProps()
  • shouldComponentUpate()
  • componentWillUpdate()/UNSAFE_componentWillUpdate() 弃用
  • render()
  • getSnapshotBeforeUpdate()
  • componentDidUpdate

getDerivedStateFromPropsgetSnapshotBeforeUpdate时,componentWillReceiveProps()/UNSAFE_componentWillReceiveProps()componentWillUpdate()/UNSAFE_componentWillUpdate()无效。

componentWillReceiveProps()/UNSAFE_componentWillReceiveProps() 弃用

UNSAFE_componentWillReceiveProps(nextprops){}
复制代码

在已挂载的组件接收新的props以前调用,通常用这个方法判断props的先后变化来更新state

须要注意的是,若是父组件致使组件从新渲染,那么即便props没有更改,也会调用次方法。

该方法将被弃用,建议使用getDeviedStateFromProps

import * as React from "react";
class App extends React.Component {
  state = {
    isWill: false,
  };

  componentWillReceiveProps(nextProps) {
    if (this.props.cur !== nextProps.cur) {
      this.setState({
        isWill:
          nextProps.cur > this.props.cur,
      });
    }
  }
  render(){
     return(
         <div>22</div>
     )
  }
}
复制代码

static getDerivedStateFromProps()

和挂载阶段一致。

shouldComponentUpdate()

shouldComponentUpdate(props,state)
复制代码

在已挂载的组件,当props或者state发生变化时,会在渲染前调用。

根据父组件的 props 和当前的 state 进行对比,返回true/false。决定是否触发后续的 UNSAFE_componentWillUpdate()render()componentDidUpdate()

React 可能将shouldComponentUpdate()认为不严格的指令,即便statefalse,也有可能致使组件从新渲染。

import * as React from "react";
class App extends React.Component {
  state = {
    isWill: false,
  };

  shouldComponentUpdate(props,state){ 
       if(props.val !== state.val){
           console.log("shouldComponentUpdate");
           return true
       }
   }
   render(){
        return(
            <div>22</div>
        )
    }
}
复制代码

getSnapshotBeforeUpdate()

getSnapshotBeforeUpdate(prevProps,prevSteate)
复制代码

在真是的 DOM 更新前调用。可获取一些有用的信息而后做为参数传递给componentDidUpdate()prevProps表示更新前的props,prevState表示更新前的state

render()以后componentDidUpdate()以前调用。此方法的返回值(snaphot)可做为componentDidUpdate()的第三个参数使用。如不须要返回值则直接返回null

getSnapshotBeforeUpdate()须要和componentDidUpdate()搭配。

componentDidUpdate()

componentDidUpdate(prevProps, prevState, snapshot)
复制代码

该方法会在更新完成后当即调用。首次渲染不会执行此方法。

当组件更新后,能够在此处对 DOM 进行操做。

能够在此阶段使用setState,触发render()但必须包裹在一个条件语句里,以免死循环。

卸载

  • componentWillUnmount()
componentWillUnmount()
复制代码

会在组件卸载和销毁以前直接调用。此方法主要用来执行一些清理工做,例如:定时器,清除事件绑定,取消网络请求。

此阶段不能调用setState,由于组件永远不会从新渲染。

总结

React 的生命周期能够查看 生命周期图谱

虽然 React 作了向下兼容,但仍是推荐你们逐渐使用新的生命周期方法。

更多详情请移步React 生命周期

相关文章
相关标签/搜索