1.前言

学习React时,学习组件的生命周期是非常重要的,了解了组件的“从无到有再到无”所经历的各个状态,对日后写高性能的组件会有很大的帮助。

2.生命周期图

React的生命周期图示如图所示,其大致分为三个阶段:初始化阶段、更新阶段、销毁阶段。

上图是一个组件从被创建出来到最后被销毁所要经历的一系列过程,所以这个过程也叫做一个组件的生命周期图。从图中我们可以看到,一个组件从创建到更新最后到被销毁,总共要经历以下几个过程

初始化阶段

  • getDefaultProps()
  • getInitialState()
  • componentWillMount()
  • render()
  • componentDidMount()

更新阶段

  • componentWillReceiveProps(nextProps)
  • shouldComponentUpdate(nextProps, nextState)
  • componentWillUpdata(nextProps, nextState)
  • componentDidUpdate()

销毁阶段

  • componentWillUnmount()

3.代码演示

了解了组件生命周期各个过程后,我们放一波代码,真正的看一看一个组件从生到死到底经历了什么。

import React, {Component} from 'react';
import ReactDOM from "react-dom"; class LifeCycle extends Component { constructor(props) {
super(props)
this.state = {
count: 0
}
} componentWillMount() {
console.group("%c%s", "color:red", '==============componentWillMount 组件挂载之前===============');
console.log('element:', document.querySelector('#lifecycle'));
} componentDidMount() {
console.group("%c%s", "color:red", '==============componentDidMount 组件挂载完毕===============');
console.log('element:', document.querySelector('#lifecycle'));
} componentWillUpdate(nextProps, nextState, nextContext) {
console.group("%c%s", "color:red", '==============componentWillUpdate 组件更新之前===============');
console.log('element:', document.querySelector('#lifecycle'));
} componentDidUpdate(prevProps, prevState, snapshot) {
console.group("%c%s", "color:red", '==============componentDidUpdate 组件更新完毕===============');
console.log('element:', document.querySelector('#lifecycle'));
} componentWillUnmount() {
console.group("%c%s", "color:red", '==============componentWillUnmount 组件销毁完毕===============');
console.log('element:', document.querySelector('#lifecycle'));
} add = () => {
this.setState({
count: this.state.count + 1
})
} destory = () => {
ReactDOM.unmountComponentAtNode(document.querySelector('#root'))
} render() {
console.group("%c%s", "color:red", '==============render 组件正在挂载===============');
console.log('element:', document.querySelector('#lifecycle'));
return (
<div id='lifecycle'>
<h1>计数器:{this.state.count}</h1>
<button onClick={this.add}>+</button>
<button onClick={this.destory}>销毁</button>
</div>
);
}
} export default LifeCycle;

运行上面代码,可以看到如下效果:

3.各个过程详解

3.1 getDefaultProps()

设置默认的props,也可以用dufaultProps设置组件的默认属性.

3.2 getInitialState()

在使用class语法时是没有这个钩子函数的,可以直接在constructor中定义this.state。此时可以访问this.props

3.3 componentWillMount()

此钩子函数在组件挂载之前被调用,从控制台打印结果可以看出,此时组件的DOM节点还未被创建,可以修改state.

3.4 render()

该函数为整个生命周期中最重要的步骤,该步骤会创建虚拟dom,进行diff算法,更新dom树。

render() 函数应该为纯函数,这意味着在不修改组件 state 的情况下,每次调用时都返回相同的结果,并且它不会直接与浏览器交互。

如需与浏览器进行交互,请在 componentDidMount() 或其他生命周期方法中执行你的操作。保持 render() 为纯函数,可以使组件更容易思考。

3.5 componentDidMount()

此钩子函数在组件挂载完毕后调用,从控制台打印结果可以看出,此时组件的DOM节点已经被成功挂载(插入 DOM 树中)。依赖于 DOM 节点的初始化应该放在这里。如需通过网络请求获取数据,此处是实例化请求的好地方。

3.6 componentWillReceiveProps(nextProps)

此钩子函数在组件接受到新的props时被调用。

3.7 shouldComponentUpdate(nextProps, nextState)

react性能优化非常重要的一环。组件接受新的state或者props时调用,我们可以设置在此对比前后两个propsstate是否相同,如果相同则让该函数返回false阻止更新(返回值默认为 true),因为相同的属性状态一定会生成相同的dom树,这样就不需要创造新的dom树和旧的dom树进行diff算法对比,节省大量性能,尤其是在dom结构复杂的时候。

例如,在本文的例子中,我们使得当计数器大于3时,不再更新。可以编写如下代码:

shouldComponentUpdate(nextProps, nextState, nextContext) {
if (nextState.count > 3) {
return false
} else {
return true
}
}

从图中我们可以看到,当计数器等于3时,再点击“+”号时,组件已经不再更新了。

3.8 componentWillUpdata(nextProps, nextState)

当组件收到新的 props 或 state 时,会在渲染之前调用此钩子函数。使用此函数可作为在组件更新发生之前需要执行的相关操作。初始渲染不会调用此方法。

注:如果 shouldComponentUpdate() 返回 false,则不会调用componentWillUpdate()

3.9 componentDidUpdate()

此钩子函数会在组件更新后会被立即调用。首次渲染不会执行此方法。

当组件更新后,可以在此处对 DOM 进行操作。如果你对更新前后的 props 进行了比较,也可以选择在此处进行网络请求。(例如,当 props 未发生变化时,则不会执行网络请求)。

componentDidUpdate(prevProps) {
// 典型用法(不要忘记比较 props):
if (this.props.userID !== prevProps.userID) {
this.fetchData(this.props.userID);
}
}

注:如果 shouldComponentUpdate() 返回值为 false,则不会调用 componentDidUpdate()

3.10 componentWillUnmount()

componentWillUnmount() 会在组件卸载及销毁之前直接调用。在此方法中执行必要的清理操作,例如,清除 timer,取消网络请求或清除在 componentDidMount() 中创建的订阅等。

componentWillUnmount()不应调用 setState(),因为该组件将永远不会重新渲染。组件实例卸载后,将永远不会再挂载它

(完)

通俗易懂了解React生命周期的更多相关文章

  1. React生命周期

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

  2. React 生命周期

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

  3. React生命周期详解

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

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

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

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

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

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

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

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

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

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

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

  9. vue生命周期和react生命周期对比

    一 vue的生命周期如下图所示(很清晰)初始化.编译.更新.销毁 二 vue生命周期的栗子 注意触发vue的created事件以后,this便指向vue实例,这点很重要 <!DOCTYPE ht ...

随机推荐

  1. 理解Android中的注解与反射

    反射 Java反射(Reflection)定义 Java反射机制是指在运行状态中 对于任意一个类,都能知道这个类的所有属性和方法:对于任何一个对象,都能够调用它的任何一个方法和属性: 这样动态获取新的 ...

  2. Java Intellij 第一个HelloWord

    前言 最近重心点都在Java, 鉴于避免一些跟我一样学习Java开始啥都不懂,不知如何下手,方便小白快速入门.故写下此文,鉴于分享. (前提是安装jdk, 建议使用版本是1.8) JDK 安装地址:h ...

  3. Java之微信公众号开发

    这次以文本回复作为案例来讲解Java相关得微信公众号开发. 首先必须要有一个个人微信公众号 个人微信公众号相关的接口权限有限,不过用于个人学习体验一下足够了,如图: 然后进入微信公众后台,点击基本配置 ...

  4. .net core 3.0 WPF中使用FolderBrowserDialog

    前言 随着.net core 3.0 的发布,WPF 也可以在 core 平台上使用了.当前的 WPF 不支持跨平台,仅能够在 Windows 平台上使用.如果想体验 WPF 跨平台开发,可以访问开源 ...

  5. Vue-CLI项目-axios模块前后端交互(类似ajax提交)

    08.31自我总结 Vue-CLI项目-axios前后端交互 一.模块的安装 npm install axios --save #--save可以不用写 二.配置main.js import axio ...

  6. [LUOGU1122] 最大子树和 - 树形动规

    题目描述 小明对数学饱有兴趣,并且是个勤奋好学的学生,总是在课后留在教室向老师请教一些问题.一天他早晨骑车去上课,路上见到一个老伯正在修剪花花草草,顿时想到了一个有关修剪花卉的问题.于是当日课后,小明 ...

  7. Java项目部署与远程调试两三事

    [开启和进行远程调试]参考https://blog.csdn.net/WSYW126/article/details/748536801.tomcat:配置catalina.sh jpda参数,主要是 ...

  8. .Net Core 3.0 IdentityServer4 快速入门

    .Net Core 3.0 IdentityServer4 快速入门 一.简介 IdentityServer4是用于ASP.NET Core的OpenID Connect和OAuth 2.0框架. 将 ...

  9. opencv::凸包-Convex Hull

    概念介绍 什么是凸包(Convex Hull),在一个多变形边缘或者内部任意两个点的连线都包含在多边形边界或者内部. 正式定义:包含点集合S中所有点的最小凸多边形称为凸包 Graham扫描算法 首先选 ...

  10. 解决Anki服务器同步问题:坚果云 & Floder sync (已测试)

    读前须知: 更新日期:2019-07-08 1.本教程面向对象为:有一定计算机知识人群 2.配合参考链接中的文章,共同食用. 3.已经过测试,可同步图片,音频,视频 4.尝试有风险,提前导出Anki卡 ...