九、【React基础】组件的生命周期

news2025/7/17 4:44:55

文章目录

  • 1、旧生命周期
    • 1.1、单组件生命周期
      • 1.1.1、生命周期
        • 1.1.1.1、初始化阶段:由 ReactDOM.render() 触发---初次渲染
        • 1.1.1.2、更新阶段:由组件内部 this.setSate() 或父组件重新render触发
        • 1.1.1.3、卸载组件:由 ReactDOM.unmountComponentAtNode() 触发
      • 1.1.2、CODE
      • 1.1.3、Result
    • 1.2、嵌套组件生命周期
      • 1.2.1、组件将要接收 props
      • 1.2.2、CODE
      • 1.2.3、Result
  • 2、新生命周期
    • 2.1、变化
      • 2.1.1、即将废弃的 3 个老钩子
      • 2.1.2、新增 2 个钩子(万年不用)
    • 2.2、新生命周期
      • 2.2.1、初始化阶段:由 ReactDOM.render() 触发---初次渲染
      • 2.2.2、更新阶段:由组件内部 this.setSate() 或父组件重新render触发
      • 2.2.3、卸载组件:由 ReactDOM.unmountComponentAtNode() 触发
    • 2.3、CODE for getSnapshotBeforeUpdate
    • 2.4、Result

访问官网 ReactDOM 了解更多DOM 的特定方法

1、旧生命周期

在这里插入图片描述

当前版本虽然依然全部可用,但是自16.x版本就开始说要删除其中的 componentWillMountcomponentWillReceivePropscomponentWillUpdate;而且这三个钩子也基本万年不用一次,建议不要使用

1.1、单组件生命周期

1.1.1、生命周期

1.1.1.1、初始化阶段:由 ReactDOM.render() 触发—初次渲染

  1. constructor()

  2. componentWillMount():组件挂载前置;组件将被挂载

  3. render() 必用

  4. componentDidMount():组件挂载完毕 常用

    1. 可以接收2个参数 (prevProps, prevState),既挂载前收到的props和初始化时创建的state
    2. 一般在这个钩子中做一些初始化的事,例如:开启定时器、发送网络请求、订阅消息

1.1.1.2、更新阶段:由组件内部 this.setSate() 或父组件重新render触发

  1. shouldComponentUpdate():组件更新阀门,判断是否进行更新

    1. 可以接收2个参数 (nextProps, nextState)
    2. 可直接调forceUpdate()绕过阀门进行强制更新
  2. componentWillUpdate():组件更新前置;组件将要更新

    1. 可以接收3个参数(prevProps, prevState, snapshot)
  3. render() 必用

  4. componentDidUpdate():组件更新完毕

1.1.1.3、卸载组件:由 ReactDOM.unmountComponentAtNode() 触发

  1. componentWillUnmount():组件卸载前置;组件将要被卸载,这里可以交代后事 常用
    1. 一般在这个钩子中做一些收尾的事,例如:关闭定时器、取消订阅消息

1.1.2、CODE

<!DOCTYPE html>
<html lang="en">
<head>
	<meta charset="UTF-8">
	<title>2_react生命周期(旧)</title>
</head>
<body>
	<!-- 准备好一个“容器” -->
	<div id="test"></div>

	<!-- 引入react核心库 -->
	<script type="text/javascript" src="../js/react.development.js"></script>
	<!-- 引入react-dom,用于支持react操作DOM -->
	<script type="text/javascript" src="../js/react-dom.development.js"></script>
	<!-- 引入babel,用于将jsx转为js -->
	<script type="text/javascript" src="../js/babel.min.js"></script>

	<script type="text/babel">
		//创建组件
		class Count extends React.Component {

			//构造器
			constructor(props) {
				console.log('Count---constructor');
				super(props)
				//初始化状态
				this.state = { count: 0 }
			}

			//组件将要挂载的钩子
			componentWillMount() {
				console.log('Count--组件挂载前置--componentWillMount');
			}

			//组件挂载完毕的钩子
			componentDidMount() {
				console.log('Count--组件挂载完毕--componentDidMount');
			}

			//控制组件更新的“阀门”
			shouldComponentUpdate() {
				console.log('Count--组件更新阀门--shouldComponentUpdate');
				return true // 必须返回boolean且只有返回true才会继续执行更新流程
			}

			//组件将要更新的钩子
			componentWillUpdate() {
				console.log('Count--组件更新前置--componentWillUpdate');
			}

			//组件更新完毕的钩子
			componentDidUpdate() {
				console.log('Count--组件更新完毕--componentDidUpdate');
			}

			//组件将要卸载的钩子
			componentWillUnmount() {
				console.log('Count--组件卸载前置--componentWillUnmount');
			}

			//加1按钮的回调
			add = () => {
				//获取原状态
				const { count } = this.state
				//更新状态
				this.setState({ count: count + 1 })
			}

			//卸载组件按钮的回调
			death = () => {
				ReactDOM.unmountComponentAtNode(document.getElementById('test'))
			}

			//强制更新按钮的回调
			force = () => {
				this.forceUpdate() // 绕过更新阀门直接强制更新
			}

			render() {
				console.log('Count--组件渲染钩子--render');
				const { count } = this.state
				return (
					<div>
						<h2>当前求和为:{count}</h2>
						<button onClick={this.add}>点我+1</button>
						<button onClick={this.death}>卸载组件</button>
						<button onClick={this.force}>不更改任何状态中的数据,强制更新一下</button>
					</div>
				)
			}
		}

		//渲染组件
		ReactDOM.render(<Count />, document.getElementById('test'))
	</script>
</body>
</html>

1.1.3、Result

在这里插入图片描述


1.2、嵌套组件生命周期

1.2.1、组件将要接收 props

  • componentWillReceiveProps(props):组件接收 props 前置
    • 注意点:第一次传的不算(首次渲染不会调此钩子),如果更名为 componentWillReceiveNewProps 更好理解

1.2.2、CODE

//父组件A
class A extends React.Component {
    //初始化状态
    state = { carName: '奔驰' }

    changeCar = () => {
        this.setState({ carName: '奥拓' })
    }

    render() {
        return (
            <div>
                <div>我是A组件</div>
                <button onClick={this.changeCar}>换车</button>
        		<hr />
            	<B carName={this.state.carName} />
			</div>
        )
    }
}

//子组件B
class B extends React.Component {
    //组件将要接收新的props的钩子
    componentWillReceiveProps(props) {
        console.log('B---componentWillReceiveProps', props);
    }

    //控制组件更新的“阀门”
    shouldComponentUpdate() {
        console.log('B---shouldComponentUpdate');
        return true
    }
    //组件将要更新的钩子
    componentWillUpdate() {
        console.log('B---componentWillUpdate');
    }

    //组件更新完毕的钩子
    componentDidUpdate() {
        console.log('B---componentDidUpdate');
    }

    render() {
        console.log('B---render');
        return (
            <div>我是B组件,接收到的车是:{this.props.carName}</div>
    	)
    }
}

//渲染组件
ReactDOM.render(<A/>, document.getElementById('test'))

1.2.3、Result

在这里插入图片描述


2、新生命周期

在这里插入图片描述

2.1、变化

2.1.1、即将废弃的 3 个老钩子

  • componentWillMount
  • componentWillReceiveProps
  • componentWillUpdate

如果在新版本想继续使用这三个废弃的钩子,则必须在前面加上 “UNSAFE_” 前缀,这里的 “unsafe” 不是指安全性,而是表示使用这些生命周期的代码在 React 的未来版本中更有可能出现 bug,尤其是在启用异步渲染之后。具体可参考官博 异步渲染之更新(为未来规划计)。

2.1.2、新增 2 个钩子(万年不用)

  • getDerivedStateFromProps:从Props获取派生状态。此方法适用于==罕见==的用例,即 state 的值在任何时候都取决于 props。派生状态会导致代码冗余,并使组件难以维护
    • 可以接收2个参数,没错就是 (props, state)
    • 必须声明为 static 静态方法
    • 必须返回一个 state 对象或者 null
  • getSnapshotBeforeUpdate:在最近一次渲染输出(提交到 DOM 节点)之前调用。它使得组件能在发生更改之前从 DOM 中捕获一些信息(例如,滚动位置)。此生命周期方法的任何返回值将作为参数传递给 componentDidUpdate()此用法并不常见,但它可能出现在 UI 处理中,如需要以特殊方式处理滚动位置的聊天线程等。
    • 可以接收2个参数 (prevProps, prevState)
    • 必须返回 snapshot 的值或 null

2.2、新生命周期

新钩子已经红色标出,由于根本不用,所以未加粗突出,甚至完全可以忽略这俩小透明

2.2.1、初始化阶段:由 ReactDOM.render() 触发—初次渲染

  1. constructor()

  2. static getDerivedStateFromProps()

  3. render() 必用

  4. componentDidMount() 常用

2.2.2、更新阶段:由组件内部 this.setSate() 或父组件重新render触发

  1. static getDerivedStateFromProps()

  2. shouldComponentUpdate()

  3. render() 必用

  4. getSnapshotBeforeUpdate

  5. componentDidUpdate()

2.2.3、卸载组件:由 ReactDOM.unmountComponentAtNode() 触发

  1. componentWillUnmount() 常用

2.3、CODE for getSnapshotBeforeUpdate

<!DOCTYPE html>
<html lang="en">
<head>
	<meta charset="UTF-8">
	<title>4_getSnapShotBeforeUpdate的使用场景</title>
	<style>
		.list{
			width: 200px;
			height: 150px;
			background-color: skyblue;
			overflow: auto;
		}
		.news{
			height: 30px;
		}
	</style>
</head>
<body>
	<!-- 准备好一个“容器” -->
	<div id="test"></div>
	
	<!-- 引入react核心库 -->
	<script type="text/javascript" src="../js/17.0.1/react.development.js"></script>
	<!-- 引入react-dom,用于支持react操作DOM -->
	<script type="text/javascript" src="../js/17.0.1/react-dom.development.js"></script>
	<!-- 引入babel,用于将jsx转为js -->
	<script type="text/javascript" src="../js/17.0.1/babel.min.js"></script>

	<script type="text/babel">
		class NewsList extends React.Component{

			state = {newsArr:[]}

			componentDidMount(){
				setInterval(() => {
					//获取原状态
					const {newsArr} = this.state
					//模拟一条新闻
					const news = '新闻'+ (newsArr.length+1)
					//更新状态
					this.setState({newsArr:[news,...newsArr]})
				}, 1000);
			}

			getSnapshotBeforeUpdate(){
				return this.refs.list.scrollHeight
			}

			componentDidUpdate(preProps,preState,height){
				this.refs.list.scrollTop += this.refs.list.scrollHeight - height
			}

			render(){
				return(
					<div className="list" ref="list">
						{
							this.state.newsArr.map((n,index)=>{
								return <div key={index} className="news">{n}</div>
							})
						}
					</div>
				)
			}
		}
		ReactDOM.render(<NewsList/>,document.getElementById('test'))
	</script>
</body>
</html>

2.4、Result

滑动到哪就可以让内容停在哪,不会随着数据增加而被压到底下

在这里插入图片描述



小白学习参考视频:尚硅谷React教程

中文官网:State & 生命周期

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/36527.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

流媒体传输 - RTP 荷载 H264

H264 码流结构 H264 码流是由很多 NAL Unit 组成&#xff0c;所有 NAL Unit 均存在一个八位数据的 NAL Unit Header &#xff0c;这八位数据也充当此 RTP 有效负载格式的有效负载头。一个 NAL Unit Header 的语法如下: ---------------|0|1|2|3|4|5|6|7|--------|F|NRI| Type…

深分页Scroll

ES对from size是有限制的&#xff0c;from和size二者之和不能超过1W 原理&#xff1a; fromsize在ES查询数据的方式&#xff1a; 第一步现将用户指定的关键进行分词。 第二步将词汇去分词库中进行检索&#xff0c;得到多个文档的id。 第三步去各个分片中去拉取指定的数据。耗…

JUC总结-基础篇

juc是什么&#xff1f; JUC是java.util.concurrent包的简称&#xff0c;在Java5.0添加&#xff0c;目的就是为了更好的支持高并发任务。让开发者进行多线程编程时减少竞争条件和死锁的问题&#xff01; juc脑图 juc总结 juc多数工具都是依赖volatile关键字保持可见性和禁止指…

ovs vxlan 时延和吞吐

设计云时到底要不要用vxlan&#xff0c;如果用vxlan到底要不要购买比较贵的smart nic做offload&#xff0c;采用软件vxlan还是硬件交换机vxlan&#xff0c;很难决策&#xff0c;这儿简单测试一下&#xff0c;给个参考&#xff0c;资源终究是有限的&#xff0c;成本还是有考虑的…

Flutter splash 屏幕

Flutter splash 屏幕 原文 https://medium.com/bedirhanssaglam/flutter-splash-screen-a8cafec52c8e 前言 启动画面通常被特别大的应用程序用来通知用户程序正在加载过程中。它们提供的反馈表明&#xff0c;一个漫长的过程正在进行中。有时&#xff0c;启动画面中的进度条会指…

【MYSQL】在线恢复主从复制方案

一、恢复前提 因复杂情况&#xff0c;从库无法从binlog中恢复主从复制关系&#xff0c;需要从备份文件中恢复。恢复过程的几个关键点为&#xff1a; 1、从库现有数据的清理。本方案采用覆盖的方式&#xff0c;导出时添加add-drop参数即可。还有一个方案是手动删除数据文件&…

1990-2021年全国各省外商直接投资水平

1990-2021年全国各省外商直接投资水平 1、包括全国30省&#xff0c;不含西藏 2、指标包括&#xff1a; 行政区划代码、长江经济带、年份、地区、经度、纬度、GDP(亿元)、外商直接投资(美元)(万美元)、人民币对美元汇率(美元1)(元)、外商直接投资(万元)、外商直接投资水平 3、…

第三章:CompletableFuture

Future接口复习FutureTask 实现类Future 编码的优缺点优点缺点get() 方法导致阻塞isDone() 轮询总结CompletableFutureCompletableFuture 为什么会出现&#xff1f;CompletableFuture 架构图CompletionStageCompletableFuture 四个静态方法CompletableFuture 减少阻塞和轮询注意…

Elasticsearch 8.4.1 配置自签名证书和启用Https

一、背景 某次安全扫描过程中&#xff0c;发现环境存在【SSL证书不可信】和【SSL自签名证书】漏洞&#xff1b;漏洞描述&#xff1a; 此服务的X.509证书链未由认可的证书颁发机构签名。如果远程主机是生产中的公共主机&#xff0c;这将取消SSL的使用&#xff0c;因为任何人都可…

干货分享:超级浏览器使用感受

在亚马逊做工艺品时间挺长的了&#xff0c;来说说我这几年使用超级浏览的感受。 现在做跨境的就跟做国内的电商平台一样卷了&#xff0c;不仅产品要新奇独特、要包邮价格还要有优势&#xff0c;可以说以前跨境电商是卖方市场&#xff0c;现在已经妥妥变成买方市场了。但这是国际…

python基础之模块与列表

文章目录一、模块模块名也是一个标识符二、列表高级变量类型&#xff1a;在python中&#xff0c;所有非数字型变量都支持以下特点&#xff1a;列表的定义&#xff1a;列表函数使用&#xff1a;关键字、函数和方法科普&#xff1a;列表的迭代 遍历&#xff1a;一、模块 模块是p…

一文了解 Go 中的指针和结构体

一文了解 Go 中的指针和结构体前言指针指针的定义获取和修改指针所指向变量的值结构体结构体定义结构体的创建方式小结耐心和持久胜过激烈和狂热。 前言 前面的两篇文章对 Go 语言的基础语法和基本数据类型以及几个复合数据类型进行介绍&#xff0c;本文将对 Go 里面的指针和结…

机器学习-(手推)线性回归-最小二乘法(矩阵表达)、几何意义

一、最小二乘法&#xff08;矩阵表达&#xff09;误差平均分散每个样本 如下数学推到过程&#xff08;手推&#xff01;&#xff01;&#xff01;&#xff09;&#xff1a; 数据介绍&#xff1a; D{(x1,y1),(x2,y2),......(xn,yn)&#xff0c; Xi&#xff08;P维列向量&…

行列向量的维数和个数的关系【三秩相等作为桥梁】

前置知识 1.列向量组维数增加时&#xff0c;向量组的极大无关组增加&#xff08;或不变&#xff09;。 2. 三秩相等 向量组证明 直观证明 这两个列向量显然是相关的。 这两个列向量当a和b取k和2k的时候相关&#xff08;k为任意常数&#xff09;&#xff0c;当不是k和2k的时…

【2-Docker安装部署ElasticSearch和Kibanan详细步骤】

一.知识回顾 【0.ElasticSearch专栏在这里哟&#xff0c;想要学习的可自行进入专栏学习】 【1-ElasticSearch的基本介绍与用途、ElasticSearch中一些基本的概念、倒排索引的基本概念】 二.Docker安装部署ElasticSearch 2.1 docker pull 从镜像仓库中拉拉取ElasticSearch的镜像…

【零基础入门SpringMVC】第三期——请求域添加数据与视图

一、域对象共享数据 SpringMVC 中有哪些域对象&#xff1f; Request请求域&#xff0c;代表一次请求&#xff0c;从浏览器开启到关闭Session请求域&#xff0c;代表一次会话&#xff0c;从服务器开启到关闭【一次getSession获得了cookie&#xff0c;这个会话没关闭&#xff0c;…

Romantics三大浪漫(编译原理+操作系统+计算机图形学)

Romantics三大浪漫 一、编译原理1.1 研究翻译的科学1.2 编译器和解释器1.3 编译的流程(JIT为例)1.4 词法分析器1.5 多有限状态机提取Token- 实现词法分析器lexer1.6 实现流的peek和putBack操作一、编译原理 本章目标: 提升编程能力 区别于面向研究人员、学者的编译原理教学&a…

CSS学习笔记(三)

her~~llo&#xff0c;我是你们的好朋友Lyle&#xff0c;是名梦想成为计算机大佬的男人&#xff01; 博客是为了记录自我的学习历程&#xff0c;加强记忆方便复习&#xff0c;如有不足之处还望多多包涵&#xff01;非常欢迎大家的批评指正。 目录 一、CSS 的三大特性 1.1 层叠…

mybatis复习05,mybatis的缓存机制(一级缓存和二级缓存及第三方缓存)

mybatis复习05,mybatis的缓存机制&#xff08;一级缓存和二级缓存&#xff09;MyBatis的缓存机制MyBatis的一级缓存MyBatis的二级缓存二级缓存的相关配置MyBatis缓存查询的顺序整合第三方缓存EHCacheEHCache配置文件说明&#xff1a;MyBatis的缓存机制 MyBatis作为持久化框架&…

社区故事|SmartX 用户社区技术发烧友独家专访

小伙伴们&#xff0c;SmartX 用户社区已经陪伴我们走过近两年的时光&#xff0c;这期间有一千多位小伙伴加入我们&#xff0c;共同讨论问题、分享经验。今天&#xff0c;SmartX 用户社区的一线记者小乐为我们带来了独家采访&#xff0c;揭秘社区中两位技术发烧友的幕后故事&…