React18原理: 生命周期中特别注意事项
概述
- 生命周期就是一个组件从诞生到销毁的全过程(包含错误捕获,这里暂且不聊这个)
- react 在组件的生命周期中注册了一系列的钩子函数
- 支持开发者在其中嵌入代码,并在适当的时机运行
- 生命周期本质上就是组件中的钩子函数,主要有三个主要的钩子
- 挂载
- 更新
- 卸载
首次挂载
-
1 )初始化 constructor
- 同一个类组件对象只会运行一次
- 所以经常来做一些初始化的操作
- 同一个组件对象被多次创建,它们的 constructor 互不干扰
- 注意
- 在 constructor 中尽量避免(禁止) 使用 setState
- setState会造成页面的重新渲染
- 但是在 初始化 阶段,页面都还没有将真实dom挂载到页面上,是没有任何重新渲染的意义的
- 除异步情况,比如 setInterval 中使用 setState 是没问题的,
- 因为在执行的时候页面早已渲染完成,但也最好不要使用,容易引起奇怪的问题,参考
constructor(props) {super(props);this.state = {num: 1}// 不可以,直接warningthis.setState({num: this.state.num + 1});// 可以使用,但不建议setInterval(() => {this.setState({num: this.state.num + 1});}, 1000); }
-
2 )获取最新的属性和状态 static getDerivedStateFromProps
- 该方法是一个静态属性,静态属性就是为了不让使用 this 和 setState
- 在16版本之前不存在,在新版生命周期中,主要用于取代 componentWillMount 和 comonentWillReceiveProps
- 因为这两个老生命周期方法在协议开发者不规范的使用下极易产生一些反模式的 bug
- 因为是静态方法,所以,你在其中根本拿不到 this, 更不可能调用 setState
- 该方法在挂载阶段和更新阶段都会运行,它有两个参数 props 和 state 当前的属性值和状态
- 它的返回值会合并掉当前的状态 (state), 如果返回了非 Object 的值
- 那么它啥都不会做,如果返回的是 Object, 那它将会跟当前的状态合并
- 可以理解为 Object.assign, 通常情况下,几乎不怎么使用该方法
/*** 静态方法,首次挂载和更新渲染都会运行该方法 * props 当前属性 * state 当前状态 */ static getDerivedStateFromProps(props, state) {// return 1; // 没用return {num: 999, // 合并到当前 state 对象} }
-
3 )创建 vDOM render
- 最重要的生命周期,没有之一,用来生成虚拟节点vDom树
- 该方法只要遇到需要重新渲染都会运行
- 同样,在 render 中也严禁使用 setState, 因为会导致无限递归重新渲染导致 爆栈
render() {// 严禁使用this.setState({num: 1})return (<>(this.state.num)</>) }
-
4 )挂载到页面渲染成真实Dom componentDidMount
- 该方法只会运行一次,在 首次渲染 时页面将 真实 dom 挂载完毕之后运行
- 通常在这里做一些异步操作,比如开启定时器,发起网络请求,获取真实DOM等
- 在该方法中,可以大胆使用 setState, 因为页面已经渲染完成
- 执行完该钩子函数后,组件正式进入到 活跃 状态
componentDidMount() {// 初始化或异步代码this.setState({})setInterval(() => {}); // 简单模拟document.querySelectorAll('div'); }
更新阶段
-
更新阶段会更新 state 或 更新 props
-
1 )获取最新的属性和状态 static getDerivedStateFromProps
-
2 )是否重新渲染 shouldComponentUpdate
- 在执行完 static getDerivedStateFromProps 后,会执行该钩子函数
- 该方法通常用来做 性能优化,它的返回值 (boolean) 决定了是否要进行 渲染 更新
- 该方法有两个参数 nextProps 和 nextState 表示此次更新(下一次)的属性和状态
- 通常,我们会将当前值与此次要更新的值做比较来决定是否要进行重新渲染
- 在react 中,官方提供了一个基础版的优化组件 PureComponent 就是一个 HOC 高阶组件
- 内部实现就是帮我们用 shouldComponentUpdate 做了浅比较
- 注意,继承了 PureComponent 后, 不需要再使用 SCU 进行优化
/*** 决定是否要重新进行渲染* nextProps 此次更新的属性* nextState 此次更新的状态* returns boolean*/ shouldComponentUpdate(nextProps, nextState) {// 伪代码,如果当前的值和下一次的值相等,那么就没有更新渲染的必要了if (this.props === nextProps && this.state === nextState) {return false;}return true; }
-
3 )更新vDOM render
-
4 )获取更新之前的状态 getSnapshotBeforeUpdate
- 如果 shouldComponentUpdate 返回是 true,
- 那么就会运行 render 重新生成虚拟 DOM 树来进行对比更新
- 该方法运行在 render 之后,表示 真实 DOM 已经构建完成
- 但还没有渲染到页面中,可以理解为更新前的 快照,通常用来做一些附加的DOM操作
- 比如,突然想针对某个 class 的真实元素做一些事情,那么就可以在此方法中获取元素
- 并修改,该函数有两个参数 prevProps 和 prevState 表示此次更新前的属性和状态
- 该函数的返回值 snapshot,会作为 componentDidUpdate 的第三个参数
/*** 获取更新前的快照,通常用来做一些附加的DOM操作* prevProps 更新前的属性* prevState 更新前的状态*/ getSnapshotBeforeUpdate(prevProps, prevState) {// 获取真实DOM在渲染到页面前作一些附加操作...document.querySelectorAll('div').forEach(it => it.innerHTML = '123')return 'componentDidUpdate的第三个参数' }
-
5 )更新后挂载成真实DOM componentDidUpdate
- 该方法是 更新阶段 最后运行的 钩子函数,跟
getSnapshotBeforeUpdate
不同的是 - 它运行时间点是在 真实DOM 挂载到页面后,通常也会使用该方法来操作一些真实的DOM
- 它有三个参数分别为: prevProps, prevState, snapshot, 跟 Snapshot 钩子函数一样
- 表示更新前的属性,状态,Snapshot 钩子函数的返回值
/*** prevProps 更新前的属性* prevState 更新前的状态* snapshot getSnapshotBeforeUpdate 的返回值*/ componentDidUpdate(prevProps, prevState, snapshot) {document.querySelectorAll('div').forEach(it => it.innerHTML = snapshot) }
- 该方法是 更新阶段 最后运行的 钩子函数,跟
卸载阶段
- 组件被卸载 componentWillUnMount
- 该 钩子函数 属于卸载阶段中唯一的方法
- 如果组件在渲染的过程中被卸载了,React会报出 Warning: Can’t perform a React state update on an unmounted component 的警告
- 所以,通常爱组件被卸载时,做清除副作用的操作
componentWillUnmount() {// 组件倍卸载前清理副作用clearInterval(timer1);clearTimeout(timer2);this.setState = () => {}; }
相关文章:
React18原理: 生命周期中特别注意事项
概述 生命周期就是一个组件从诞生到销毁的全过程(包含错误捕获,这里暂且不聊这个)react 在组件的生命周期中注册了一系列的钩子函数支持开发者在其中嵌入代码,并在适当的时机运行生命周期本质上就是组件中的钩子函数,主要有三个主要的钩子 挂…...

【C语言】Linux内核bind系统调用代码
一、Linux 4.9内核bind系统调用代码注释 int __sys_bind(int fd, struct sockaddr __user *umyaddr, int addrlen) {struct socket *sock; // 定义socket对象的指针struct sockaddr_storage address; // 用于存储从用户空间复制过来的地址int err…...

Ubuntu下Anaconda+PyCharm搭建PyTorch环境
这里主要介绍在condapytorch都正确安装的前提下,如何通过pycharm建立开发环境; Ubuntu下AnacondaPyCharm搭建PyTorch环境 系统环境:Ubuntu22.04 conda: conda 23.11.0 pycharm:如下 condapytorch的安装教程介绍,请点击这里&…...

酷开科技荣获“消费者服务之星”称号后的未来展望
恭喜酷开科技荣获2023年第四季度黑猫平台“消费者服务之星”称号!这是对酷开科技长期以来坚持用户至上、用心服务的肯定和认可。作为OTT行业的佼佼者,酷开科技一直秉承着“以用户为中心”的服务理念,不断追求卓越品质,为用户提供更…...
UVA1449 Dominating Patterns 题解
UVA1449 Dominating Patterns 题解 板子题诶。 解法 AC 自动机模板题,因为数据范围比较小,所以不加拓扑排序优化建图即可通过本题。这里简单介绍一下拓扑排序优化建图。 在查找时,每次都暴力的条 f a i l fail fail 指针是很消耗时间的&…...

【C语言】数据结构#实现堆
目录 (一)堆 (1)堆区与数据结构的堆 (二)头文件 (三)功能实现 (1)堆的初始化 (2)堆的销毁 (3)插入数据 …...

AES加密中的CBC和ECB
目录 1.说明 2.ECB模式(base64) 3.CBC模式 4.总结 1.说明 AES是常见的对称加密算法,加密和解密使用相同的密钥,流程如下: 主要概念如下: ①明文 ②密钥 用来加密明文的密码,在对称加密算…...

【C++】类和对象(四)
前言:在类和对象中,我们走过了十分漫长的道路,今天我们将进一步学习类和对象,类和对象这块荆棘地很长,各位一起加油呀。 💖 博主CSDN主页:卫卫卫的个人主页 💞 👉 专栏分类:高质量&a…...
XGB-5: DART Booster
XGBoost 主要结合了大量的回归树和一个小的学习率。在这种情况下,早期添加的树是重要的,而晚期添加的树是不重要的。 Vinayak 和 Gilad-Bachrach 提出了一种将深度神经网络社区的 dropout 技术应用于梯度提升树的新方法,并在某些情况下报告了…...

HiveSQL——不使用union all的情况下进行列转行
参考文章: HiveSql一天一个小技巧:如何不使用union all 进行列转行_不 union all-CSDN博客文章浏览阅读881次,点赞5次,收藏10次。本文给出一种不使用传统UNION ALL方法进行 行转列的方法,其中方法一采用了concat_wsposexplode()方…...

Python环境下基于指数退化模型和LSTM自编码器的轴承剩余寿命预测
滚动轴承是机械设备中关键的零部件之一,其可靠性直接影响了设备的性能,所以对滚动轴承的剩余使用寿命(RUL)进行预测是十分必要的。目前,如何准确地对滚动轴承剩余使用寿命进行预测,仍是一个具有挑战的课题。对滚动轴承剩余寿命评估…...
无人机竞赛视觉算法开发流程开源计划(询问大家意见)
本科中参加过一系列的无人机机器人竞赛,像电赛、工训赛、机器人大赛这些,有一些比较常用的方案打算开源一下。现在读研了,也算是对本科的一个总结,但是还是想看看大家意见,大家有什么需求可以在评论区说,我…...

DMA直接内存访问,STM32实现高速数据传输使用配置
1、DMA运用场景 随着智能化、信息化的不断推进,嵌入式设备的数据处理量也呈现指数级增加,因此对于巨大的数据量处理的情况时,必须采取其它的方式去替CPU减负,以保证嵌入式设备性能。例如SD卡存储器和音视频、网络高速通信等其它情…...

Web安全研究(六)
文章目录 HideNoSeek: Camouflaging(隐藏) Malicious JavaScript in Benign ASTs文章结构Introjs obfuscationmethodologyExample HideNoSeek: Camouflaging(隐藏) Malicious JavaScript in Benign ASTs CCS 2019 CISPA 恶意软件领域,基于学习的系统已经非常流行&am…...

python3 中try 异常调试 raise 异常抛出
一、什么是异常? 异常即是一个事件,该事件会在程序执行过程中发生,影响了程序的正常执行。 一般情况下,在Python无法正常处理程序时就会发生一个异常。 异常是Python对象,表示一个错误。 当Python脚本发生异常时我…...
Java中的序列化是什么?如何实现对象的序列化和反序列化?请解释Serializable接口的作用是什么?请解释transient关键字的作用是什么?为什么会使用它?
Java中的序列化是指将对象转换为字节序列的过程,以便可以在网络上传输或将其保存到持久存储介质中。反序列化则是将字节序列重新转换回对象的过程。Java提供了一种称为序列化(Serialization)的机制来实现对象的序列化和反序列化。 要实现对象…...

二维差分---三维差分算法笔记
文章目录 一.二维差分构造差分二维数组二维差分算法状态dp求b[i][j]数组的二维前缀和图解 二.三维前缀和与差分三维前缀和图解:三维差分核心公式图解:模板题 一.二维差分 给定一个原二维数组a[i][j],若要给a[i][j]中以(x1,y1)和(x2,y2)为对角线的子矩阵中每个数都加上一个常数…...

D. Divisible Pairs
思路:我们预处理出每个数分别摸上xy的值,用map存一下,然后遍历每个数,如果a b是x的倍数的话,那么他们模x的值相加为x,如果a - b是y的倍数的话,那么他们的模y的值相等。 代码: voi…...

【教程】Kotlin语言学习笔记(二)——数据类型(持续更新)
写在前面: 如果文章对你有帮助,记得点赞关注加收藏一波,利于以后需要的时候复习,多谢支持! 【Kotlin语言学习】系列文章 第一章 《认识Kotlin》 第二章 《数据类型》 文章目录 【Kotlin语言学习】系列文章一、基本数据…...
react 插槽
问题开发当中会经常出现组件十分相似的组件,只有一部分是不同的 解决: 父组件:在引用的时候 import { Component } from "react"; import Me from "../me";const name <div>名称</div> class Shoop extends Compone…...
React hook之useRef
React useRef 详解 useRef 是 React 提供的一个 Hook,用于在函数组件中创建可变的引用对象。它在 React 开发中有多种重要用途,下面我将全面详细地介绍它的特性和用法。 基本概念 1. 创建 ref const refContainer useRef(initialValue);initialValu…...

iPhone密码忘记了办?iPhoneUnlocker,iPhone解锁工具Aiseesoft iPhone Unlocker 高级注册版分享
平时用 iPhone 的时候,难免会碰到解锁的麻烦事。比如密码忘了、人脸识别 / 指纹识别突然不灵,或者买了二手 iPhone 却被原来的 iCloud 账号锁住,这时候就需要靠谱的解锁工具来帮忙了。Aiseesoft iPhone Unlocker 就是专门解决这些问题的软件&…...

el-switch文字内置
el-switch文字内置 效果 vue <div style"color:#ffffff;font-size:14px;float:left;margin-bottom:5px;margin-right:5px;">自动加载</div> <el-switch v-model"value" active-color"#3E99FB" inactive-color"#DCDFE6"…...

零基础设计模式——行为型模式 - 责任链模式
第四部分:行为型模式 - 责任链模式 (Chain of Responsibility Pattern) 欢迎来到行为型模式的学习!行为型模式关注对象之间的职责分配、算法封装和对象间的交互。我们将学习的第一个行为型模式是责任链模式。 核心思想:使多个对象都有机会处…...

JVM虚拟机:内存结构、垃圾回收、性能优化
1、JVM虚拟机的简介 Java 虚拟机(Java Virtual Machine 简称:JVM)是运行所有 Java 程序的抽象计算机,是 Java 语言的运行环境,实现了 Java 程序的跨平台特性。JVM 屏蔽了与具体操作系统平台相关的信息,使得 Java 程序只需生成在 JVM 上运行的目标代码(字节码),就可以…...

基于 TAPD 进行项目管理
起因 自己写了个小工具,仓库用的Github。之前在用markdown进行需求管理,现在随着功能的增加,感觉有点难以管理了,所以用TAPD这个工具进行需求、Bug管理。 操作流程 注册 TAPD,需要提供一个企业名新建一个项目&#…...

并发编程 - go版
1.并发编程基础概念 进程和线程 A. 进程是程序在操作系统中的一次执行过程,系统进行资源分配和调度的一个独立单位。B. 线程是进程的一个执行实体,是CPU调度和分派的基本单位,它是比进程更小的能独立运行的基本单位。C.一个进程可以创建和撤销多个线程;同一个进程中…...

手机平板能效生态设计指令EU 2023/1670标准解读
手机平板能效生态设计指令EU 2023/1670标准解读 以下是针对欧盟《手机和平板电脑生态设计法规》(EU) 2023/1670 的核心解读,综合法规核心要求、最新修正及企业合规要点: 一、法规背景与目标 生效与强制时间 发布于2023年8月31日(OJ公报&…...
Python竞赛环境搭建全攻略
Python环境搭建竞赛技术文章大纲 竞赛背景与意义 竞赛的目的与价值Python在竞赛中的应用场景环境搭建对竞赛效率的影响 竞赛环境需求分析 常见竞赛类型(算法、数据分析、机器学习等)不同竞赛对Python版本及库的要求硬件与操作系统的兼容性问题 Pyth…...

【深度学习新浪潮】什么是credit assignment problem?
Credit Assignment Problem(信用分配问题) 是机器学习,尤其是强化学习(RL)中的核心挑战之一,指的是如何将最终的奖励或惩罚准确地分配给导致该结果的各个中间动作或决策。在序列决策任务中,智能体执行一系列动作后获得一个最终奖励,但每个动作对最终结果的贡献程度往往…...