当前位置: 首页 > news >正文

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原理: 生命周期中特别注意事项

概述 生命周期就是一个组件从诞生到销毁的全过程(包含错误捕获&#xff0c;这里暂且不聊这个)react 在组件的生命周期中注册了一系列的钩子函数支持开发者在其中嵌入代码&#xff0c;并在适当的时机运行生命周期本质上就是组件中的钩子函数&#xff0c;主要有三个主要的钩子 挂…...

【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都正确安装的前提下&#xff0c;如何通过pycharm建立开发环境&#xff1b; Ubuntu下AnacondaPyCharm搭建PyTorch环境 系统环境&#xff1a;Ubuntu22.04 conda: conda 23.11.0 pycharm:如下 condapytorch的安装教程介绍&#xff0c;请点击这里&…...

酷开科技荣获“消费者服务之星”称号后的未来展望

恭喜酷开科技荣获2023年第四季度黑猫平台“消费者服务之星”称号&#xff01;这是对酷开科技长期以来坚持用户至上、用心服务的肯定和认可。作为OTT行业的佼佼者&#xff0c;酷开科技一直秉承着“以用户为中心”的服务理念&#xff0c;不断追求卓越品质&#xff0c;为用户提供更…...

UVA1449 Dominating Patterns 题解

UVA1449 Dominating Patterns 题解 板子题诶。 解法 AC 自动机模板题&#xff0c;因为数据范围比较小&#xff0c;所以不加拓扑排序优化建图即可通过本题。这里简单介绍一下拓扑排序优化建图。 在查找时&#xff0c;每次都暴力的条 f a i l fail fail 指针是很消耗时间的&…...

【C语言】数据结构#实现堆

目录 &#xff08;一&#xff09;堆 &#xff08;1&#xff09;堆区与数据结构的堆 &#xff08;二&#xff09;头文件 &#xff08;三&#xff09;功能实现 &#xff08;1&#xff09;堆的初始化 &#xff08;2&#xff09;堆的销毁 &#xff08;3&#xff09;插入数据 …...

AES加密中的CBC和ECB

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

【C++】类和对象(四)

前言&#xff1a;在类和对象中&#xff0c;我们走过了十分漫长的道路&#xff0c;今天我们将进一步学习类和对象&#xff0c;类和对象这块荆棘地很长&#xff0c;各位一起加油呀。 &#x1f496; 博主CSDN主页:卫卫卫的个人主页 &#x1f49e; &#x1f449; 专栏分类:高质量&a…...

XGB-5: DART Booster

XGBoost 主要结合了大量的回归树和一个小的学习率。在这种情况下&#xff0c;早期添加的树是重要的&#xff0c;而晚期添加的树是不重要的。 Vinayak 和 Gilad-Bachrach 提出了一种将深度神经网络社区的 dropout 技术应用于梯度提升树的新方法&#xff0c;并在某些情况下报告了…...

HiveSQL——不使用union all的情况下进行列转行

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

Python环境下基于指数退化模型和LSTM自编码器的轴承剩余寿命预测

滚动轴承是机械设备中关键的零部件之一&#xff0c;其可靠性直接影响了设备的性能&#xff0c;所以对滚动轴承的剩余使用寿命(RUL)进行预测是十分必要的。目前&#xff0c;如何准确地对滚动轴承剩余使用寿命进行预测&#xff0c;仍是一个具有挑战的课题。对滚动轴承剩余寿命评估…...

无人机竞赛视觉算法开发流程开源计划(询问大家意见)

本科中参加过一系列的无人机机器人竞赛&#xff0c;像电赛、工训赛、机器人大赛这些&#xff0c;有一些比较常用的方案打算开源一下。现在读研了&#xff0c;也算是对本科的一个总结&#xff0c;但是还是想看看大家意见&#xff0c;大家有什么需求可以在评论区说&#xff0c;我…...

DMA直接内存访问,STM32实现高速数据传输使用配置

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

Web安全研究(六)

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

python3 中try 异常调试 raise 异常抛出

一、什么是异常&#xff1f; 异常即是一个事件&#xff0c;该事件会在程序执行过程中发生&#xff0c;影响了程序的正常执行。 一般情况下&#xff0c;在Python无法正常处理程序时就会发生一个异常。 异常是Python对象&#xff0c;表示一个错误。 当Python脚本发生异常时我…...

Java中的序列化是什么?如何实现对象的序列化和反序列化?请解释Serializable接口的作用是什么?请解释transient关键字的作用是什么?为什么会使用它?

Java中的序列化是指将对象转换为字节序列的过程&#xff0c;以便可以在网络上传输或将其保存到持久存储介质中。反序列化则是将字节序列重新转换回对象的过程。Java提供了一种称为序列化&#xff08;Serialization&#xff09;的机制来实现对象的序列化和反序列化。 要实现对象…...

二维差分---三维差分算法笔记

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

D. Divisible Pairs

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

【教程】Kotlin语言学习笔记(二)——数据类型(持续更新)

写在前面&#xff1a; 如果文章对你有帮助&#xff0c;记得点赞关注加收藏一波&#xff0c;利于以后需要的时候复习&#xff0c;多谢支持&#xff01; 【Kotlin语言学习】系列文章 第一章 《认识Kotlin》 第二章 《数据类型》 文章目录 【Kotlin语言学习】系列文章一、基本数据…...

react 插槽

问题开发当中会经常出现组件十分相似的组件&#xff0c;只有一部分是不同的 解决&#xff1a; 父组件:在引用的时候 import { Component } from "react"; import Me from "../me";const name <div>名称</div> class Shoop extends Compone…...

eNSP-Cloud(实现本地电脑与eNSP内设备之间通信)

说明&#xff1a; 想象一下&#xff0c;你正在用eNSP搭建一个虚拟的网络世界&#xff0c;里面有虚拟的路由器、交换机、电脑&#xff08;PC&#xff09;等等。这些设备都在你的电脑里面“运行”&#xff0c;它们之间可以互相通信&#xff0c;就像一个封闭的小王国。 但是&#…...

Leetcode 3576. Transform Array to All Equal Elements

Leetcode 3576. Transform Array to All Equal Elements 1. 解题思路2. 代码实现 题目链接&#xff1a;3576. Transform Array to All Equal Elements 1. 解题思路 这一题思路上就是分别考察一下是否能将其转化为全1或者全-1数组即可。 至于每一种情况是否可以达到&#xf…...

java 实现excel文件转pdf | 无水印 | 无限制

文章目录 目录 文章目录 前言 1.项目远程仓库配置 2.pom文件引入相关依赖 3.代码破解 二、Excel转PDF 1.代码实现 2.Aspose.License.xml 授权文件 总结 前言 java处理excel转pdf一直没找到什么好用的免费jar包工具,自己手写的难度,恐怕高级程序员花费一年的事件,也…...

前端导出带有合并单元格的列表

// 导出async function exportExcel(fileName "共识调整.xlsx") {// 所有数据const exportData await getAllMainData();// 表头内容let fitstTitleList [];const secondTitleList [];allColumns.value.forEach(column > {if (!column.children) {fitstTitleL…...

《通信之道——从微积分到 5G》读书总结

第1章 绪 论 1.1 这是一本什么样的书 通信技术&#xff0c;说到底就是数学。 那些最基础、最本质的部分。 1.2 什么是通信 通信 发送方 接收方 承载信息的信号 解调出其中承载的信息 信息在发送方那里被加工成信号&#xff08;调制&#xff09; 把信息从信号中抽取出来&am…...

前端开发面试题总结-JavaScript篇(一)

文章目录 JavaScript高频问答一、作用域与闭包1.什么是闭包&#xff08;Closure&#xff09;&#xff1f;闭包有什么应用场景和潜在问题&#xff1f;2.解释 JavaScript 的作用域链&#xff08;Scope Chain&#xff09; 二、原型与继承3.原型链是什么&#xff1f;如何实现继承&a…...

MySQL中【正则表达式】用法

MySQL 中正则表达式通过 REGEXP 或 RLIKE 操作符实现&#xff08;两者等价&#xff09;&#xff0c;用于在 WHERE 子句中进行复杂的字符串模式匹配。以下是核心用法和示例&#xff1a; 一、基础语法 SELECT column_name FROM table_name WHERE column_name REGEXP pattern; …...

项目部署到Linux上时遇到的错误(Redis,MySQL,无法正确连接,地址占用问题)

Redis无法正确连接 在运行jar包时出现了这样的错误 查询得知问题核心在于Redis连接失败&#xff0c;具体原因是客户端发送了密码认证请求&#xff0c;但Redis服务器未设置密码 1.为Redis设置密码&#xff08;匹配客户端配置&#xff09; 步骤&#xff1a; 1&#xff09;.修…...

JVM虚拟机:内存结构、垃圾回收、性能优化

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

Mysql8 忘记密码重置,以及问题解决

1.使用免密登录 找到配置MySQL文件&#xff0c;我的文件路径是/etc/mysql/my.cnf&#xff0c;有的人的是/etc/mysql/mysql.cnf 在里最后加入 skip-grant-tables重启MySQL服务 service mysql restartShutting down MySQL… SUCCESS! Starting MySQL… SUCCESS! 重启成功 2.登…...