React 中组件的生命周期会经历如下三个过程:装载过程、更新过程、卸载过程。
  • 装载过程:组件实例被创建和插入 DOM 树的过程;
  • 更新过程:组件被重新渲染的过程;
  • 卸载过程:组件从 DOM 树中删除的过程。

注意:装载过程与卸载过程在组件的生命周期中只会执行一次,更新过程可以多次执行。

在这三个过程中,分别依次调用了组件的生命周期函数。

React 组件生命周期总体流程图如下:

一、装载过程

在这个过程中组件被创建,装载过程在组件的生命周期中只会被执行一次,调用的生命周期函数有:

  • defaultProps / getDefaultProps()
  • constructor() / getInitialState()
  • componentWillMount()
  • render()
  • conponentDidMount()

1、defaultProps:

组件类的一个静态属性,严格来讲这里不属于组件的生命周期的一部分,用于设置组件 props 的默认值。

  1. class Counter extends Component {
  2. static defaultProps = {
  3. count: 0,
  4. };
  5. render() {
  6. return (
  7. <div>当前值为:{this.props.count}</div>
  8. );
  9. }
  10. };

在调用组件时如果未设置 props.count,这样 props.count === undefined , 其将被设置默认为 0 :

 
  1. render() {
  2. return <Counter /> ; // 渲染后显示为 0
  3. }

如果调用组件时设置 props.count={null} , 这样渲染出来为 null :

 
  1. render() {
  2. return <Counter count={null} /> ; // 渲染后显示为 null
  3. }

他是在执行 React 的 createElement() 时去获取并赋值给 props 的,发生在组件实例化之前。

2、constructor

constructor 是 ES6 中 class 的构造函数,组件初始化调用的,所以它在组件生命周期函数中最先执行,这里主要做下面两件事情:

  • 初始化组件的 state。 它是组件初始化实例时最先执行的一个函数,因此在这里初始化 state ;
  • 方法的绑定。在 ES6 语法下,类的每个成员函数在执行时的 this 指向并不是和类的实例自动绑定的, 而构造函数中,this指向就是当前组件实例,为了方便将来调用,往往在构造函数中将组件实例的函数使用 bind(this) 这种方式,让当前实例中的函数调用时,this 始终是指向当前组件实例。
 
  1. class Counter extends Component {
  2. // 设置默认 props 的值
  3. static defaultProps = {
  4. count: 0,
  5. };
  6. // 构造函数 construcor
  7. constructor(props) {
  8. super(props);
  9. this.state = {
  10. count: 0,
  11. };
  12. this.handleIncrease = this.handleIncrease.bind(this);
  13. }
  14. // 点击增加1
  15. handleIncrease(){
  16. let addCounter = this.state.counter;
  17. this.setState({
  18. counter: addCounter + 1
  19. })
  20. }
  21. render() {
  22. return (
  23. <div>
  24. 当前 props 值为:{this.props.count}
  25. <br />
  26. 当前 state 值为:{this.state.counter}
  27. <button onClick={this.handleIncrease}>点击增加</button>
  28. </div>
  29. );
  30. }
  31. };

3、componentWillMount

准备装载组件。它在组件实例化并初始化数据完成以后,组件 render() 之前调用。

官方文档说避免在该方法中引入任何的副作用或订阅,所以我们不建议在此生命周期函数内获取数据或修改 state; 如果有需求在 render() 前一定要修改 state,最好是在 constructor 里进行。

4、render

确定需要更新组件时调用 render,根据 diff 算法,渲染界面,生成需要更新的虚拟 DOM 数据。它并不做实际的渲染动作,只是返回了一个 JSX 描述结构,最终是由 React 来操作渲染过程。

render 函数是 React 组件中最重要的函数,一个组件中可以没有其他的生命周期函数,但一定要有 render 函数,如果一个组件没有东西可呈现,这个组件的 render 函数定义返回 null 或 false;

render() 是一个纯函数,所以在此声明周期内不能 setState。

5、componentDidMount

在组件装载后调用。这时已经生成了真实的 DOM 节点。

在这个函数中我们可以获取数据,改变状态,直接改变 DOM 等操作。

注意:并不是在调用 render() 函数之后立即调用了此函数,调用 render() 函数只是返回了一个 JSX 对象供 React 调用决定如何渲染,在 React 库把所有组件渲染完成再完成装载,这时才会依次调用各个组件的 componentDidMount 函数,表示这个组件已经挂载到 DOM 上了。

以上装载过程的生命周期函数只会执行一次

二、更新过程

更新过程中依次执行的生命周期函数有:

  • componentWillReceiveProps
  • shouldComponentUpdate
  • componentWillUpdate
  • render
  • componentDidUpdate

并不是每次更新都会依次调用以上全部函数,会根据不同的变化依次执行相关的函数。

1、componentWillReceiveProps(nextProps)

子组件的 props 发生改变及父组件的 render 函数被调用都会触发子组件的此函数。我们可以根据 nextProps 同步本地的 state,但最好要先比较 this.props 与 nextPorps 在做操作。 
本组件中通过 this.setState 方法触发的更新不会触发此函数。

2、shouldComponentUpdate(nextProps, nextState)

当组件接收到新的 props 和 state 改变的话,都会触发调用,返回 Boolean,默认返回的是 true。 
返回 true 继续进行下面的生命周期函数;返回 false 不更新组件。 
这个组件中不允许改变 state。 
我们可以利用此特点来优化项目,避免不必要的渲染,提高性能。

 
  1. shouldComponentUpdate(nextProps, nextState) {
  2. return this.props.count !== nextProps.count || this.state.counter !== nextState.counter;
  3. }

3、componentWillUpdate

在 shouldComponentUpdate 函数返回 true 时,会依次调用 componentWillUpdate、render 和 componentDidUpdate 函数。 
此函数内不可以改变 state,如果需要更新状态,请在 componentWillReceiveProps 中调用 this.setState()。

4、render 
这次 render() 和装载阶段的 render() 没有区别,只不过是在不同的阶段调用。

前一个 render 是在组件第一次加载时调用的,也就是初次渲染; 
后一个 render 是除去第一次之后调用的,也就是再渲染。

5、componentDidUpdate 
在组件再次渲染之后调用的。和 componentDidMount 一样,在这个函数中可以使用 this.refs 获取真实 DOM。

此函数内不可以改变 state

三、卸载阶段

componentWillUnmount

当组件要被从界面上移除的时候,就会调用。 
在这个函数中,可以做一些组件相关的清理工作,例如取消计时器、网络请求等。

代码 github 地址:https://github.com/mqp0713/react-lifestyle

React 生命周期简介的更多相关文章

  1. React生命周期

    在react生命周期中,分2段执行,一个挂载的生命周期,一个是组件发生了数据变动,或者事件触发而引发的更新生命周期. 注:react生命周期很重要,对于很多组件场景的应用发挥重要作用,而且不熟悉生命周 ...

  2. React 生命周期

    前言 学习React,生命周期很重要,我们了解完生命周期的各个组件,对写高性能组件会有很大的帮助. Ract生命周期 React 生命周期分为三种状态 1. 初始化 2.更新 3.销毁 初始化 1.g ...

  3. Android之Activity生命周期简介

    概述 有图有真相,所以先上图: 上图是从Android官网截下的Activity的生命周期流程图,结构非常清晰,它描述了Activity在其生命周期中所有可能发生的情况以及发生的先后顺序,下面就将结合 ...

  4. React生命周期详解

    React生命周期图解: 一.旧版图解: 二.新版图解: 从图中,我们可以清楚知道React的生命周期分为三个部分:  实例化.存在期和销毁时. 旧版生命周期如果要开启async rendering, ...

  5. React生命周期简单详细理解

    前言 学习React,生命周期很重要,我们了解完生命周期的各个组件,对写高性能组件会有很大的帮助. Ract生命周期 React 生命周期分为三种状态 1. 初始化 2.更新 3.销毁 初始化 1.g ...

  6. 22.1 、react生命周期(一)

    在每个react组件中都有以下几个生命周期方法~我们需要在不同阶段进行讨论 组件生命周期概述 1.初始化 在组件初始化阶段会执行 constructor static getDerivedStateF ...

  7. react 生命周期钩子里不要写逻辑,否则不生效

    react 生命周期钩子里不要写逻辑,否则不生效,要把逻辑写在函数里,然后在钩子里调用函数,否则会出现问题.

  8. react复习总结(2)--react生命周期和组件通信

    这是react项目复习总结第二讲, 第一讲:https://www.cnblogs.com/wuhairui/p/10367620.html 首先我们来学习下react的生命周期(钩子)函数. 什么是 ...

  9. React生命周期执行顺序详解

    文章内容转载于https://www.cnblogs.com/faith3/p/9216165.html 一.组件生命周期的执行次数是什么样子的??? 只执行一次: constructor.compo ...

随机推荐

  1. JDK 1.8 -> 1.7

    电脑刚开始装的是1.8 version, 然后又需要用到1.7. 所以就要把1.8 降为1.7, 网上有很多说把1.8删掉,这种做法我是不建议的,那么要用的时候呢?又得装回来多蛋疼.. JDK 1.8 ...

  2. 依赖注入之setter注入---只需修改配置,电脑就可以安装不同的打印机;读取properties配置文件并创建实例;实现不采用new的方式直接实例化对象

    1.项目截图 2.黑白打印机类 package com.example.demo.printer; public class GrayPrinter implements Printer{ @Over ...

  3. console.log()中的%d,%s等代表的输出类型

    在console.log()或console.debug()中输出时会有%d,%s等符号. %s for a String value 字符类型 %d or %i for a Integer valu ...

  4. Shiro-ini认证

    #2019.2.2 shiro的ini认证 先用IDEA创建一个普通的MAVEN项目,并导入依赖 <!--Junit单元测试--> <groupId>junit</gro ...

  5. Tomcat配置及不依赖IDEA部署web应用

    http:tomcat.apache.org 下载tomcat文件包 我使用的tomcat9的版本 Tomcat9014使用的是Servlet4.0 解压即可,目录如下 bin :启动和关闭tomca ...

  6. Tensorflow描述张量的维度:阶,形状以及维数

    张量 TensorFlow用张量这种数据结构来表示所有的数据.你可以把一个张量想象成一个n维的数组或列表.一个张量有一个静态类型和动态类型的维数.张量可以在图中的节点之间流通. 阶 在TensorFl ...

  7. 基于Verilog的带FIFO输出缓冲的串口接收接口封装

    一.模块框图及基本思路 rx_module:串口接收的核心模块,详细介绍请见“基于Verilog的串口接收实验” rx2fifo_module:rx_module与rx_fifo之间的控制模块,其功能 ...

  8. caog

    import pandas as pd#匹配可发库存1. import oslst=os.listdir(r'E:\每日必做\琪琪小象库存')lst1=[]for i in lst: if i[:2] ...

  9. python小白的自述

    python语言作为目前受用面比较广泛的一种语言,具有简单易学,功能强大的特点.初次接触python完全是由于好奇心,正是因为python的出现,才让我觉得编程不是那么的神秘了.不过作为一个编程小白来 ...

  10. 网络请求————ProxyHandler实现代理ip

    from urllib import request #这个是没有使用代理的 # resp = request.urlopen('http://httpbin.org/ip') # print(res ...