React生命周期钩子函数
前言
所谓的生命周期就是指某个事物从开始到结束的各个阶段,就好像是把人的出生到死亡分成一个个阶段,你肯定是在出生阶段起名字,而不会在成年或者死亡的阶段去起名字。当然在 React.js 中指的是组件从创建到销毁的过程,React 实例从开始创建、初始化数据、编译模板、挂载Dom→渲染、更新→渲染、卸载等一系列过程,我们称这是 React 的生命周期,各个阶段有相对应的事件钩子,用户可以在特定的阶段调用特定的方法。每个阶段组件内部的属性都是不一样的,所以一般特定的钩子做特定的事。
一、React生命周期图
【1】过去
【2】现在
二、React生命周期演变
这么多生命周期钩子,实际上总结起来只有三个过程:挂载、更新、卸载,挂载和卸载只会执行一次,更新会执行多次。
一个完整的React组件生命周期会依次调用如下钩子
【1】生命周期演变
React版本 | 挂载阶段 | 更新阶段 | 卸载阶段 |
之前(React 16.3 之前) |
|
|
componentWillUnmount |
现在 |
|
|
componentWillUnmount |
【2】废弃和新增
原来(React v16.0前)的生命周期在React v16推出的Fiber之后就不合适了,因为如果要开启async rendering,在render函数之前的所有函数,都有可能被执行多次。所以除了shouldComponentUpdate,其他在render函数之前的所有函数(componentWillMount,componentWillReceiveProps,componentWillUpdate)都被getDerivedStateFromProps替代。
以下生命周期钩子将被逐渐废弃,看出特点了么,都是带有will的钩子
- componentWillMount
- componentWillReceiveProps
- componentWillUpdate
引入了以下两个生命周期钩子
- getDerivedStateFromProps
- getSnapshotBeforeUpdate
【3】注意
- getDerivedStateFromProps前面要加上static保留字,声明为静态方法,不然会被react忽略掉
getDerivedStateFromProps里面的this为undefined
三、React生命周期方法介绍
【1】constructor(props):初始化钩子函数
constructor()中完成了React数据的初始化,它接受两个参数:props和context,当想在函数内部使用这两个参数时,需使用super()传入这两个参数。如果没有初始化状态(state),并且没有绑定方法,通常不需要为 React 组件实现一个构造函数。
注意:
- 只要使用了constructor()就必须写super(),否则会导致this指向错误。
- 不需要在构造函数中调用 setState(),只需将初始状态设置给 this.state 即可 。
React 构造函数通常只用于两个目的:
- 通过分配一个对象到this.state来初始化本地state
- 将事件处理程序方法绑定到实例
constructor(props) {super(props);// 不要这样做this.state = { color: props.color };
}
【2】componentWillMount():组件将要挂载时触发的函数
这是组件挂载到DOM之前的生命周期钩子。componentWillMount()一般用的比较少,它更多的是在服务端渲染时使用。它代表的过程是组件已经经历了constructor()初始化数据后,但是还未渲染DOM时。
【3】render():组件挂载时触发的函数
render函数是类组件中唯一必须的方法,其余生命周期不是必须要写。 组件渲染时会走到该生命周期,展示的组件都是由 render() 生命周期的返回值来决定。render函数会插入jsx生成的dom结构,react会生成一份虚拟dom树,在每一次组件更新时,在此react会通过其diff算法比较更新前后的新旧DOM树,比较以后,找到最小的有差异的DOM节点,并重新渲染。
【4】componentDidMount():组件挂载完成时触发的函数
这是组件挂载到DOM之后的生命周期钩子。组件第一次渲染完成,此时dom节点已经生成,可以在这里调用ajax请求,返回数据setState后组件会重新渲染
【5】componentWillUnmount ():组件将要销毁时触发的函数
这是组件卸载之前的生命周期钩子,在此处完成组件的卸载和数据的销毁。
【6】componentWillReceiveProps (nextProps):父组件中改变了props传值时触发的函数
- 在接受父组件改变后的props需要重新渲染组件时用到的比较多
- 接受一个参数nextProps
- 通过对比nextProps和this.props,将nextProps的state为当前组件的state,从而重新渲染组件
componentWillReceiveProps (nextProps) {nextProps.isOpen !== this.props.isOpen && this.setState({isOpen:nextProps.isOpen}, () => {//将state更新为nextProps,在setState的第二个参数(回调)可以打印出新的state})
}
【7】shouldComponentUpdate(nextProps,nextState):是否要更新组件时触发的函数
- 这个生命周期钩子是一个开关,判断是否需要更新,主要用来优化性能(部分更新),如果开发者调用this.forceUpdate强制更新,React组件会无视这个钩子。
- 对于组件来说,只有状态发生改变,才需要重新渲染。所以shouldComponentUpdate生命周期钩子暴露了两个参数,开发者可以通过比较this.props和nextProps、this.state和nextState来判断状态到底有没有发生改变,再相应的返回true或false。
- 唯一用于控制组件重新渲染的生命周期,由于在react中,setState以后,state发生变化,组件会进入重新渲染的流程,在这里return false可以阻止组件的更新
- 因为react父组件的重新渲染会导致其所有子组件的重新渲染,这个时候其实我们是不需要所有子组件都跟着重新渲染的,因此需要在子组件的该生命周期中做判断
【8】componentWillUpdate (nextProps,nextState):将要更新组件时触发的函数
shouldComponentUpdate生命周期钩子返回true以后,组件进入重新渲染的流程,进入componentWillUpdate,这里同样可以拿到nextProps和nextState。
【9】componentDidUpdate(prevProps,prevState):组件更新完成时触发的函数
这是组件更新之后触发的生命周期钩子,组件更新完毕后,react只会在第一次初始化成功会进入componentDidmount,之后每次重新渲染后都会进入这个生命周期,这里可以拿到prevProps和prevState,即更新前的props和state。
【10】static getDerivedStateFromProps(nextProps,prevState):静态方法生命周期钩子
getDerivedStateFromProps 会在调用 render 方法之前调用,并且在初始挂载及后续更新时都会被调用。它应返回一个对象来更新 state,如果返回 null 则不更新任何内容。为什么getDerivedStateFromProps生命周期钩子要设计成静态方法呢?因为这样开发者就访问不到this也就是实例了,也就不能在里面调用实例方法或者setsState了,用一个静态函数getDerivedStateFromProps来取代被废弃的其他几个生命周期函数,就是强制开发者在render之前只做无副作用的操作,而且能做的操作局限在根据props和state决定新的state 而已。
【11】 getSnapshotBeforeUpdate(prevProps,prevState):保存状态快照
它是用来代替componentWillUpdate生命周期钩子函数的,常见的 componentWillUpdate 的用例是在组件更新前,读取当前某个 DOM 元素的状态,并在 componentDidUpdate 中进行相应的处理。
这两者的区别在于:
- 在 React 开启异步渲染模式后,在 render 阶段读取到的 DOM 元素状态并不总是和 commit 阶段相同,这就导致在
componentDidUpdate 中使用 componentWillUpdate 中读取到的 DOM 元素状态是不安全的,因为这时的值很有可能已经失效了。- getSnapshotBeforeUpdate 会在最终的 render 之前被调用,也就是说在 getSnapshotBeforeUpdate 中读取到的 DOM 元素状态是可以保证与 componentDidUpdate 中一致的。此生命周期返回的任何值都将作为参数传递给componentDidUpdate()。
四、实例
【1】挂载阶段
创建一个子组件,代码如下,在父组件引入渲染即可
import React ,{Component} from 'react'class Child extends Component{// 初始化constructor(props){console.log('01构造函数') super(props)this.state={}}// 组件将要挂载时候触发的生命周期函数componentWillMount(){console.log('02组件将要挂载')}// 组件挂载完成时候触发的生命周期函数componentDidMount(){console.log('04组件挂载完成')}// 组件挂载时触发的生命周期函数render(){console.log('03数据渲染render')return(<div>Child组件</div>) }
}
export default Child
控制台打印结果顺序如下:
01构造函数
02组件将要挂载
03数据渲染render
04组件挂载完成
【2】更新阶段
数据更新的话第一步是shouldComponentUpdate确认是否要更新数据,当这个函数返回的是true的时候才会进行更新,并且这个函数可以声明两个参数nextProps和nextState,nextProps是父组件传给子组件的值,nextState是数据更新之后值,这两个值可以在这个函数中获取到。第二步当确认更新数据之后componentWillUpdate将要更新数据,第三步依旧是render,数据发生改变render重新进行了渲染。第四步是componentDidUpdate数据更新完成。
import React, { Component } from 'react'class Child extends Component {constructor(props) {super(props)this.state = {msg: '我是一个msg数据'}}//是否要更新数据,如果返回true才会更新数据shouldComponentUpdate(nextProps, nextState) {console.log('01是否要更新数据')return true; //返回true,确认更新}//将要更新数据的时候触发的生命周期函数componentWillUpdate() {console.log('02组件将要更新')}//更新完成时触发的生命周期函数componentDidUpdate() {console.log('04组件更新完成')}//更新数据方法setMsg() {this.setState({msg: '我是改变后的msg数据'})}render() {console.log('03数据渲染render')return (<div>{this.state.msg}<button onClick={() => this.setMsg()}>点我更新msg的数据</button></div>)}
}
export default Child
点击按钮更新数据,控制台打印结果顺序如下:
01是否要更新数据
02组件将要挂载
03数据渲染render
04组件更新完成
五、参考
React官网: https://zh-hans.reactjs.org/
文章每周持续更新,可以微信搜索「 前端大集锦 」第一时间阅读,回复【视频】【书籍】领取200G视频资料和30本PDF书籍资料
React生命周期钩子函数相关推荐
- React 生命周期 钩子函数
React15 挂载过程 // 完成了React数据的初始化. props.state constructor() // 组件已经完成初始化数据,但是还未渲染DOM时执行的逻辑 componentWi ...
- reactjs组件生命周期:componentWillReceiveProps及新旧版本生命周期钩子函数对比
reactjs组件生命周期:componentWillReceiveProps及新旧版本生命周期钩子函数对比
- 详解Vue八大生命周期钩子函数
摘要:Vue为生命周期中的每个状态都设置了钩子函数(监听函数) .每当Vue实例处于不同的生命周期时,对应的函数就会被触发调用. 本文分享自华为云社区<一文带你弄懂Vue八大生命周期钩子函数&g ...
- 不来看看这些 VUE 的生命周期钩子函数? | 原力计划
作者 | huangfuyk 责编 | 王晓曼 出品 | CSDN 博客 VUE的生命周期钩子函数:就是指在一个组件从创建到销毁的过程自动执行的函数,包含组件的变化.可以分为:创建.挂载.更新.销毁四 ...
- uni-app中的生命周期钩子函数
1.应用级(App)生命周期钩子函数--App.vue -- 类似于小程序 onLaunch:应用启动了,每次运行只能执行一次 onShow:应用再次显示出来,每次显示出来都会调用 onHide:应用 ...
- 实战 Vue 之生命周期钩子函数执行顺序
实战 Vue 之生命周期钩子函数执行顺序 生命周期钩子函数 父组件与子组件执行顺序 生命周期钩子函数 beforeCreate:实例刚被创建出来,data 数据和 methods 方法还未被初始化,不 ...
- vue的组件/data的参数/组件传值/插槽/侦听器/生命周期钩子函数
目录 组件结构 组件的命名规则: 组件的data参数 <font color='red'> 组件的父子传值prop(通信) <font color='red'>组件的子--&g ...
- Vue3 生命周期钩子函数
一.Vue3生命周期钩子 setup() : 开始创建组件之前,在 beforeCreate 和 created 之前执行,创建的是 data 和 method onBeforeMount() : 组 ...
- Vue的生命周期钩子函数介绍
感谢内容提供者:金牛区吴迪软件开发工作室 Vue的生命周期钩子函数介绍 vue生命周期共分为四个阶段 一:实例创建 二:DOM渲染 三:数据更新 四:销毁实例 共有八个基本钩子函数 1.beforeC ...
- vue生命周期钩子函数的正确使用方式
对于vue生命周期我们还是要先了解清楚,因为不同的生命期用不同的钩子函数,先上图: 遇到的一个问题 在我的项目中,常用的生命周期钩子函数一直都是mounted,对于大部分情况,都是屡试不爽.捷报频传~ ...
最新文章
- pytorch 损失函数总结
- [笔记]modelsim前仿后仿各种问题
- 情感分析基于词典(算例代码)
- 继承(父类,子类的继承方式,成员变量、静态变量的引用方法)
- Golang——枚举(iota)的使用
- 360浏览器清除缓存_微信缓存清理教程
- XFS:大数据环境下Linux文件系统的未来?
- 知识点学习之LPCNet
- 输入年份和月份输出该月有多少天python_题目内容:读入一个年份和月份,输出该月有多少天(考虑闰年),用s? 爱问知识人...
- [转]计算机经典书籍
- ubuntu安装nvidia显卡驱动黑屏nvidia-smi黑屏-显卡故障
- Linux原理与应用A卷广东科技,Linux操作系统应用选择题附答案(广东开放大学)...
- #217-[哈希]好人卡
- 申请软件著作权的流程有哪些?让专业人士带你了解
- apache的HttpClient的默认重试机制
- ICPC——2021台湾站(A B C D E J)
- 《炬丰科技-半导体工艺》IC制造化学清洗过程中硅上重金属污染的表面光电压监测
- 什么是STW以及CMS和G1优缺点?
- 嵌入式 Linux 开发工具篇问题整理//C语言测试(杨辉三角、递归调用实现阶乘、计算器、统计字符串出现次数)//2018.07.12.//
- Python生成密码字典教程
热门文章
- Python网站服务器搭建,python 最快速搭建一个网站
- 手机市场的竞争,用户价值才是硬道理
- 裁判文书网爬虫(2019.5.15更新)
- iqooneo5桌面原子组件教程分享
- jsonp跨域的原理
- 蒟蒻的做题录(时间)
- 小觅双目摄像头标准版视觉惯性 SLAM DEMO
- Java微信授权登陆
- 【软件开发规范一】《Java开发规范》
- OpenCV中出现“Microsoft C++ 异常: cv::Exception,位于内存位置 0x0000005C8ECFFA80 处。”的异常...