通俗易懂了解React生命周期
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
时调用,我们可以设置在此对比前后两个props
和state
是否相同,如果相同则让该函数返回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生命周期的更多相关文章
- React生命周期
在react生命周期中,分2段执行,一个挂载的生命周期,一个是组件发生了数据变动,或者事件触发而引发的更新生命周期. 注:react生命周期很重要,对于很多组件场景的应用发挥重要作用,而且不熟悉生命周 ...
- React 生命周期
前言 学习React,生命周期很重要,我们了解完生命周期的各个组件,对写高性能组件会有很大的帮助. Ract生命周期 React 生命周期分为三种状态 1. 初始化 2.更新 3.销毁 初始化 1.g ...
- React生命周期详解
React生命周期图解: 一.旧版图解: 二.新版图解: 从图中,我们可以清楚知道React的生命周期分为三个部分: 实例化.存在期和销毁时. 旧版生命周期如果要开启async rendering, ...
- React生命周期简单详细理解
前言 学习React,生命周期很重要,我们了解完生命周期的各个组件,对写高性能组件会有很大的帮助. Ract生命周期 React 生命周期分为三种状态 1. 初始化 2.更新 3.销毁 初始化 1.g ...
- 22.1 、react生命周期(一)
在每个react组件中都有以下几个生命周期方法~我们需要在不同阶段进行讨论 组件生命周期概述 1.初始化 在组件初始化阶段会执行 constructor static getDerivedStateF ...
- react 生命周期钩子里不要写逻辑,否则不生效
react 生命周期钩子里不要写逻辑,否则不生效,要把逻辑写在函数里,然后在钩子里调用函数,否则会出现问题.
- react复习总结(2)--react生命周期和组件通信
这是react项目复习总结第二讲, 第一讲:https://www.cnblogs.com/wuhairui/p/10367620.html 首先我们来学习下react的生命周期(钩子)函数. 什么是 ...
- React生命周期执行顺序详解
文章内容转载于https://www.cnblogs.com/faith3/p/9216165.html 一.组件生命周期的执行次数是什么样子的??? 只执行一次: constructor.compo ...
- vue生命周期和react生命周期对比
一 vue的生命周期如下图所示(很清晰)初始化.编译.更新.销毁 二 vue生命周期的栗子 注意触发vue的created事件以后,this便指向vue实例,这点很重要 <!DOCTYPE ht ...
随机推荐
- 【linux】jdk安装及环境变量配置
登录linux后,切换目录到 /usr/local cd /user/local 在/usr/local目录新建文件夹java用于存放jdk文件 mkdir java 在文件夹java中下载jdk文件 ...
- kali切换到西电源
准备研究kali的openvas,打开发现居然没有.apt-get更新一下结果各种报错,换成中科大源.阿里源还是始终报错,气到吐血.最后上西电开源社区换成了西电的kali源,更新速度2m多,一气呵成~ ...
- MongoDB 走马观花(全面解读篇)
目录 一.简介 二.基本模型 BSON 数据类型 分布式ID 三.操作语法 四.索引 索引特性 索引分类 索引评估.调优 五.集群 分片机制 副本集 六.事务与一致性 一致性 小结 一.简介 Mong ...
- Nexus搭建开发组的私有仓库
一.私有仓库的价值 开发Java应用系统,用到Maven.sbt和 Gradle等构建工具,在构建过程中一般需要从互联网下载依赖库,构建私有仓库就是为了在开发组或者部门内共用,从而节省整体的下载成本和 ...
- Python3升级3.6强力Django+杀手级xadmin打造在线教育平台☝☝☝
Python3升级3.6强力Django+杀手级xadmin打造在线教育平台☝☝☝ 教程 Xadmin安装方法: settings.py 的配置
- Java并发编程总结(一)Syncronized解析
Syncronized解析 作用: )确保线程互斥的访问同步代码 )保证共享变量的修改能够及时可见 )有效解决重排序问题. 用法: )修饰普通方法(锁是当前实例对象) )修饰静态方法(锁是当前对象的C ...
- Kubernetes集群的部署方式及详细步骤
一.部署环境架构以及方式 第一种部署方式 1.针对于master节点 将API Server.etcd.controller-manager.scheduler各组件进行yum install.编译安 ...
- django安装以及配置
一.django的安装和启动 1.安装 pip3 install django==1.11.22 目前来讲1.11.22版本比较稳定 2.django的创建 命令行:cmd先去到django创建目录, ...
- AppBoxFuture: 服务模型的在线调试
框架内的服务模型(ServiceModel)用于处理各类业务逻辑(如最简单的CRUD操作),在设计时以类似于伪代码的形式存在,发布时后端会通过Roslyn转换并编译为运行时代码.为了方便开发者更简 ...
- mysql 延时注入新思路
转自先知社区https://xz.aliyun.com/t/2288 在4月的pwnhub比赛中,我们遇到了一个比较神奇的问题,如果在注入中遇到需要延时注入的情况,但服务端过滤了我们一般使用的slee ...