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 = () => {};
      }
      

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

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

相关文章

深入理解常见的设计模式

目录 引言 1. 单例模式&#xff08;Singleton Pattern&#xff09; 应用场景&#xff1a; 示例代码&#xff1a; . 工厂模式&#xff08;Factory Pattern&#xff09; 应用场景&#xff1a; 示例代码&#xff1a; 3. 观察者模式&#xff08;Observer Pattern&#xff09…

[职场] 如何通过运营面试_1 #笔记#媒体#经验分享

如何通过运营面试 盈利是公司的事情&#xff0c;而用户就是你运营的事情。你需要彻底建立一个庞大而有效的用户群&#xff0c;这样才能让你们的公司想盈利就盈利&#xff0c;想战略就战略&#xff0c;想融资就融资。 一般从事运营的人有着强大的自信心&#xff0c;后台数据分析…

JVM-虚拟机栈

虚拟机栈 Java虚拟机栈&#xff08;Java Virtual Machine Stack&#xff09;采用栈的数据结构来管理方法调用中的基本数据&#xff0c;先进后出&#xff08;First In Last Out&#xff09;,每一个方法的调用使用一个栈帧&#xff08;Stack Frame&#xff09;来保存。 接下来以…

vue3 之 通用组件统一注册全局

components/index.js // 把components中的所组件都进行全局化注册 // 通过插件的方式 import ImageView from ./ImageView/index.vue import Sku from ./XtxSku/index.vue export const componentPlugin {install (app) {// app.component(组件名字&#xff0c;组件配置对象)…

D7 Elasticsearch-Mongodb(搜索记录)

我是南城余&#xff01;阿里云开发者平台专家博士证书获得者&#xff01; 欢迎关注我的博客&#xff01;一同成长&#xff01; 一名从事运维开发的worker&#xff0c;记录分享学习。 专注于AI&#xff0c;运维开发&#xff0c;windows Linux 系统领域的分享&#xff01; 知…

mysql笔记:表设计原则

mysql笔记&#xff1a;表设计原则 表对应了一个实体 表与表之间的关系&#xff1a; 一对一 一对多 多对多 一对一关系 例如&#xff1a;用户 user和身份信息 info 子表的外键关联了父表的子健&#xff08;类型必须一样&#xff09; 一对多关系 以电商系统为例子 用户-商…

CSP-202012-1-期末预测之安全指数

CSP-202012-1-期末预测之安全指数 题目很简单&#xff0c;直接上代码 #include <iostream> using namespace std; int main() {int n, sum 0;cin >> n;for (int i 0; i < n; i){int w, score;cin >> w >> score;sum w * score;}if (sum > 0…

使用 Ant Design 的 Upload 组件实现图片

文章目录 使用 Ant Design 的 Upload 组件实现图片Upload组件itemRender自定义上传列表项的渲染方式修改图片名上传图片上传链接中添加 Bearer Token 的请求头onPreview{handlePreview}上传成功后&#xff0c;如何隐藏上传列表 使用 Ant Design 的 Upload 组件实现图片 Upload…

【第二十三课】最小生成树:prime 和 kruskal 算法(acwing858,859 / c++代码 )

目录 前言 Prime算法--加点法 acwing-858 代码如下 一些解释 Kruskal算法--加边法 acwing-859 并查集与克鲁斯卡尔求最小生成树 代码如下 一些解释 前言 之前学最短路的时候&#xff0c;我们都是以有向图为基础的&#xff0c;当时我们提到如果是无向图&#xf…

【深度学习】实验7布置,图像超分辨

清华大学驭风计划 因为篇幅原因实验答案分开上传&#xff0c; 实验答案链接http://t.csdnimg.cn/P1yJF 如果需要更详细的实验报告或者代码可以私聊博主 有任何疑问或者问题&#xff0c;也欢迎私信博主&#xff0c;大家可以相互讨论交流哟~~ 深度学习训练营 案例 7 &#xff1…

计算机毕业设计Python+django医院后勤服务系统flask

结合目前流行的 B/S架构&#xff0c;将医疗后勤服务管理的各个方面都集中到数据库中&#xff0c;以便于用户的需要。该平台在确保平台稳定的前提下&#xff0c;能够实现多功能模块的设计和应用。该平台由管理员功能模块,工作人员模块&#xff0c;患者模块&#xff0c;患者家属模…

基于SpringBoot的记账系统项目

点击以下链接获取源码&#xff1a;https://download.csdn.net/download/qq_64505944/88822660?spm1001.2014.3001.5503 Java项目-8 开发工具&#xff1a;IDEA/Eclipse,MySQL,Tomcat 项目框架&#xff1a;SpringBoot,layui 功能&#xff1a;可以按照类型和时间查询&#xff0c…

基于tomcat运行jenkins常见的报错处理

目录 1.jenkins.util.SystemProperties$Listener错误 升级jdk11可能遇到的坑 2.java.lang.RuntimeException: Fontconfig head is null, check your fonts or fonts configuration 3.There were errors checking the update sites: UnknownHostException:updates.jenkins.i…

力扣:51. N 皇后

回溯解法思路&#xff1a; 1.用二维char数组来模拟放置皇后操作&#xff0c;同时要先把先将二维数组中全部赋值为.来表示空位。 再调用回溯函数 &#xff0c;终止条件为遍历的行数等于n时结束遍历&#xff0c;把char【】【】类型的值加入到集合li1中&#xff0c;再加加入过程…

notepad++成功安装后默认显示英文怎么设置中文界面?

前几天使用电脑华为管家清理电脑后&#xff0c;发现一直使用的notepad软件变回了英文界面&#xff0c;跟刚成功安装的时候一样&#xff0c;那么应该怎么设置为中文界面呢&#xff1f;具体操作如下&#xff1a; 1、打开notepad软件&#xff0c;点击菜单栏“Settings – Prefere…

最新基于MATLAB 2021b的机器学习、深度学习实践

基于MATLAB 2021b的机器学习和深度学习实践是一个广泛的主题&#xff0c;下面是一些基本的步骤和资源&#xff0c;可以帮助你开始&#xff1a; 安装MATLAB 2021b: 首先&#xff0c;你需要安装MATLAB 2021b。你可以从MathWorks网站下载并安装最新版本的软件。学习MATLAB基础知识…

Modern C++ 内存篇1 - std::allocator VS pmr

大年三十所写&#xff0c;看到就点个赞吧&#xff01;祝读者们龙年大吉&#xff01;当然有问题欢迎评论指正。 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 1. 前言 从今天起我们开始内存相关的话题&#xff0c;内存是个很大的话题&#xff0c;一时不…

探索未来:集成存储器计算(IMC)与深度神经网络(DNN)的机遇与挑战

开篇部分&#xff1a;人工智能、深度神经网络与内存计算的交汇 在当今数字化时代&#xff0c;人工智能&#xff08;AI&#xff09;已经成为科技领域的一股强大力量&#xff0c;而深度神经网络&#xff08;DNN&#xff09;则是AI的核心引擎之一。DNN是一种模仿人类神经系统运作…

sqli.bypass靶场本地小皮环境(1-5关)

1、第一关 http://sqli.bypass/index1.php 单引号报错id1 双引号正常id1&#xff0c;应该是单引号闭合 id1--注释符用不了&#xff0c;%20和都用不了 %0a可以用 没有报错&#xff0c;用布尔盲注&#xff0c;POC&#xff1a;id1%0aand%0asubstr(ss,1,1)s%0aand%0a11 脚本跑数…

跨模态行人重识别都需要学什么

跨模态行人重识别&#xff08;Cross-Modality Person Re-identification, 简称Cross-Modality Re-ID&#xff09;是计算机视觉领域的一项挑战性任务&#xff0c;旨在跨越不同模态之间&#xff08;例如&#xff0c;可见光与红外线图像&#xff09;识别同一行人。该任务涉及图像处…