React生命周期简介

首先介绍react16.3之前的生命周期;之后介绍react16.3的生命周期的变化

react16.3之前的生命周期

react的生命周期分为三个阶段:

  1. Mounting 挂载
  2. Updating 更新
  3. Unmounting 卸载

首先列举出所有的生命周期函数,再与这三个阶段对应、解释

  constructor(props) {
    console.log('constructor');
    super(props);
  }

  componentWillMount() {
    console.log('componentWillMount');
  }

  componentDidMount() {
    console.log('componentDidMount');
  }

  componentWillReceiveProps(nextProps, nextState) {
    console.log('componentWillReceiveProps');
  }

  shouldComponentUpdate(nextProps, nextState) {
    console.log('shouldComponentUpdate');
    return true;
  }

  componentWillUpdate(nextProps, nextState) {
    console.log('componentWillUpdate');
  }

  componentDidUpdate(prevProps, prevState) {
    console.log('componentDidUpdate');
  }

  componentWillUnmount(){
    console.log('componentWillUnmount');
  }
Mounting 挂载阶段:
  • constructor():函数构造器
    • 执行次数:1
    • 作用:初始化
  • componentWillMount:DOM挂载之前的钩子函数
    * 执行次数:1
    * 作用:DOM挂载前的操作
  • componentDidMount:DOM挂载完成的钩子函数
    * 执行次数:1
    * 作用:DOM挂载完成后的操作:setState等
Updating 更新阶段:
  • componentWillReceiveProps(nextProps, nextState):父组件传递的参数发生变化的钩子函数
    * 执行次数:多次
    * 触发条件:父组件重新render时触发,(不管向子组件传递的值是否发生变化都触发)
  • shouldComponentUpdate(nextProps, nextState):判断组件是否更新的钩子函数
    * 执行次数:多次
    * 触发条件:组件挂载之后,每次调用setState后都会调用shouldComponentUpdate判断是否需要重新渲染组件。默认返回true,需要重新render。
  • componentWillUpdate(nextProps, nextState):组件将要更新的钩子函数
    * 执行次数:多次
    * 触发条件:shouldComponentUpdate返回true或者调用forceUpdate之后
    ,componentWillUpdate会被调用。
  • componentDidUpdate(prevProps, prevState):组件完成更新的钩子函数
    * 执行次数:多次
    * 触发条件:除了首次render之后调用componentDidMount,其它render结束之后都是调用componentDidUpdate。
Unmounting 卸载阶段:
  • componentWillUnmount():组件将要卸载的钩子函数
    • 执行次数:1
    • 触发条件:组件将要被卸载的时候调用。一般在componentDidMount里面注册的事件需要在这里删除;重置this.setState = (state,callback)=>{ return;};

附上代码,可自行运行查看运行顺序

/**
 * react16.3前生命周期函数
 */
import React, { Component } from 'react';
import ReactDOM from 'react-dom';

class Father extends Component {
  constructor(props) {
    super(props);
    this.state = {
      count: 1
    }
    this.handleClick = this.handleClick.bind(this);
  }

  handleClick() {
    this.setState((prevState, props) => ({
      count: prevState.count + 1
    }))
  }

  render() {
    return (
      
) } } class Child extends Component { constructor(props) { console.log('constructor'); super(props); } componentWillMount() { console.log('componentWillMount'); } componentDidMount() { console.log('componentDidMount'); } componentWillReceiveProps(nextProps, nextState) { console.log('componentWillReceiveProps'); } shouldComponentUpdate(nextProps, nextState) { console.log('shouldComponentUpdate'); return true; } componentWillUpdate(nextProps, nextState) { console.log('componentWillUpdate'); } componentDidUpdate(prevProps, prevState) { console.log('componentDidUpdate'); } componentWillUnmount() { console.log('componentWillUnmount'); } render() { console.log('render'); return (
子元素:
父组件属性count值: {this.props.count}
this.props.handleClick()} style={{ display: "inline-block", padding: "3px 5px", color: "#ffffff", background: "green", borderRadius: "3px", cursor: "pointer" }} >click me
) } } ReactDOM.render( , document.getElementById('root'))

运行结果如下

 constructor
 componentWillMount
 render
 componentDidMount

点击button按钮(click me)后的控制台运行结果如下:

constructor
componentWillMount
render
componentDidMount
componentWillReceiveProps
shouldComponentUpdate
componentWillUpdate
render
componentDidUpdate

下图反映了React组件四条更新路径:

React生命周期简介_第1张图片
react-lifecycle.png

react16.3之后的生命周期

react16.3新增了一些生命周期函数:

getDerivedStateFromProps、getSnapshotBeforeUpdate

同时FB声明在react17将删除:

componentWillMount、componentWillReceiveProps、componentWillUpdate

在16.3的版本中将保留这三个函数,并添加了别名:

UNSAFE_componentWillMount、UNSAFE_componentWillReceiveProps、UNSAFE_componentWillUpdate

在此我们主要介绍

getDerivedStateFromProps、getSnapshotBeforeUpdate

  • getDerivedStateFromProps(nextProps, prevState):从props派生出state
    * 执行次数:多次
    * 触发条件:组件实例化及接收新props后调用
    * 替代:替代原来的componentWillReceiveProps,并且加载第一次时也调用
  • getSnapshotBeforeUpdate(nextProps, prevState):从props派生出state
    * 执行次数:多次
    * 触发条件:组件render时调用
    * 返回值:返回值传递给componentDidUpdate(prevProps, prevState, snapshot)
    * 替代:替代原来的componentWillupdate
    对上面的代码简单修改如下:
/**
 * react16.3后生命周期
 */
import React, { Component } from 'react';
import ReactDOM from 'react-dom';

class Father extends Component {
  constructor(props) {
    super(props);
    this.state = {
      count: 1
    }
    this.handleClick = this.handleClick.bind(this);
  }

  handleClick() {
    this.setState((prevState, props) => ({
      count: prevState.count + 1
    }))
  }

  render() {
    return (
      
) } } class Child extends Component { constructor(props) { console.log('constructor'); super(props); this.state={ count:10 } } static getDerivedStateFromProps(nextProps, prevState) { console.log('getDerivedStateFromProps'); return { count: nextProps.count * 2, }; } componentDidMount() { console.log('componentDidMount'); } shouldComponentUpdate(nextProps, nextState) { console.log('shouldComponentUpdate'); return true; } getSnapshotBeforeUpdate(prevProps, prevState) { console.log('getSnapshotBeforeUpdate'); return 'aa'; } componentDidUpdate(prevProps, prevState, snapshot) { console.log('componentDidUpdate'); console.log(snapshot); } render() { console.log('render'); return (
子元素:
父组件属性count值: {this.props.count}
this.props.handleClick()} style={{ display: "inline-block", padding: "3px 5px", color: "#ffffff", background: "green", borderRadius: "3px", cursor: "pointer" }} >click me
) } } ReactDOM.render( ( ) , document.getElementById('root'))

执行结果如下

constructor
getDerivedStateFromProps
render
componentDidMount

点击后如下:

constructor
 getDerivedStateFromProps
render
componentDidMount
getDerivedStateFromProps
shouldComponentUpdate
render
getSnapshotBeforeUpdate
componentDidUpdate
aa

运行一下代码一看便知

你可能感兴趣的:(React生命周期简介)