setState详解

news2025/2/1 4:04:52

this. setState( [partialState], [callback])

1.[partialState] :支持部分状态更改

this, setState({
x:100 //不论总共有多少状态,我们只修改了x,其余的状态不动
});

callback :在状态更改/视图更新完毕后触发执行,也可以说只要执行了setState, callback一定会执行

发生在componentDidUpdate周期函数之后 ,DidUpdate会在任何状态更改后都触发执行;而回调函数方式,可以在指定状态更新后处理一些事情;

2.特殊:
即便我们基于shouldComponentUpdate阻止了状态/视图的更新,DidUpdate周期函数肯定不会执行了,但是我们设置的这个
callback回调函数依然会被触发执行! !

类似于Vue框架中的$nextTick! !

在React18中,setState操作都是异步的「不论是在哪执行,例如:合成事件、周期函数、定时器…」

需要注意的是,React 可能会根据不同的情况使用不同的更新方式,而不一定会将所有的 setState 操作合并成一个更新操作。

3.目的:
实现状态的批处理「统一处理」

1.有效减少更新次数,降低性能消耗
2.有效管理代码执行的逻辑顺序

4.原理:
利用了更新队列updaters 机制来处理的

在当前相同的时间段内「浏览器此时可以处理的事情中」,遇到setState会 立即放入到更新队列中!此时状态/视图还未更新。当所有的代码操作结束,会“刷新队列”「通知更新队列中的任务执行」:把所有放入的setState合并在一起执行, 只触发一次视图更新 「批处理操作」


setState的两种方式:对象式和函数式对比

在这里插入图片描述

对象式最后x为20被优化成一次性更新没有中间状态!!!函数式是20,会有中间状态


对象式和函数式在实际项目中的例子

在 React 中,当你连续地进行多个 setState 操作时,React 会将这些操作合并起来,然后一次性地进行状态更新。这种行为被称为“对象方式的合并”。

例如,你连续调用了三次 setState 方法:

this.setState({ count: this.state.count + 1 });
this.setState({ count: this.state.count + 1 });
this.setState({ count: this.state.count + 1 });

如果使用的是对象方式更新状态,React 会将这三个对象合并成一个对象,然后进行一次性的状态更新,代码会被优化为:

this.setState({ count: this.state.count + 3 });

这种合并的行为,可以避免重复更新,提升 React 应用的性能。

但是,对于一些需要进行异步操作的场景,对象方式更新状态并不是一个好的选择。因为在异步操作中,合并并不总是起作用的。

举个例子

在进行网络请求时,你可能需要等待服务器返回数据,然后将返回的数据显示在页面上。如果你在网络请求代码块中使用对象方式更新状态,那么在请求还没有返回前,React 会将多个状态更新操作合并成一个更新操作,这可能会导致页面显示不正确或者渲染出错的问题。

因此,在这种场景下,使用函数方式更新状态是更好的选择。函数方式更新状态不会进行对象合并,而是将每次状态更新的操作包裹到一个更新函数中,然后将这个函数作为参数传递给 setState 方法。使用函数方式更新状态,可以避免对象方式进行状态合并时可能带来的问题。

在函数方式中,你可以使用当前状态和当前属性进行状态的更新。这样在状态更新的过程中不依赖于当前组件的状态,所以不会有状态合并的问题,而是针对当前状态进行更新。

如果你需要在网络请求后更新状态,可以这样写:

fetchData() {
  fetchDataFromServer()
    .then((data) => {
      // 使用函数方式更新状态
      this.setState((prevState, props) => {
        // 基于先前状态进行更新
        const newData = processData(data);
        return {
          data: newData,
        };
      });
    });
}

在这个例子中,当网络请求成功后,React 不会合并 setState 操作,而是对于当前的状态使用新传入的函数进行更新。

总的来说,如果需要在异步操作中进行状态修改,并且避免状态合并带来的问题,你可以使用函数方式更新状态。

生活中的比喻

假设你正在建造一座大楼,楼房分为很多层,每层都将会有很多不同的物品放置。你已经规划好了第一层的布局,并且决定基于这个布局来规划其他的楼层。

现在假设你的朋友来参观你的大楼,他提议在第一层放置一个沙发,但是你已经决定好了第一层的布局,因此你无法加入新的物品。这就好比是在对象方式更新状态时,由于每次更新操作都会合并状态,所以在异步操作中可能会产生干扰,导致最终更新的状态并不是预期的状态。

但是如果你使用函数方式来更新状态,就好比是在楼房建造过程中,你会为每一层都规划出一个状态,然后基于这个状态去建造每一层,这样你的朋友提议在某一层加入一个沙发也不会对其他的层产生影响。因为你在每次更新状态时都会基于当前状态来执行更新操作,所以可以保证最终的状态更新会按照你的预期进行。

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

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

相关文章

lightGBM的介绍

一、lightGBM的介绍 1.lightGBM的演进过程 2.AdaBoost算法 AdaBoost(Adaptive Boosting)是一种集成学习算法,通过组合多个弱分类器来构建一个强分类器。它是由Freund和Schapire在1996年提出的,是集成学习中最早被广泛应用的算法…

JDK8-1-Lambda表达式(5)-复合 Lambda 表达式

JDK8-1-Lambda表达式(5)-复合 Lambda 表达式 JDK8 在 java.util.function 包下定义了一些默认的 函数式接口 ,如 Predicate、Consumer、Function、 Comparator (在 java.util.包下) ,这些接口提供了一些复…

运营-21.常见的内容生产方式

常见的 内容生产方式 PGC(Professionally-generated Content)专业生产内容 传统的门户网站内容生产方式,内容多由官方工作人员身或者专业的内容创造者(比如新闻记者等)创造。 UGC(User Generated Content&a…

【好书精读】网络是怎样连接的 浏览器生成消息

如果只是讲解 TCP/IP 、 以太网这些单独的技 术 , 读者就无法理解网络这个系统的全貌 ; 如果无法理解网络的全貌 , 也 就无法理解每一种网络技术背后的本质意义 ; 而如果无法理解其本质意义 , 就只能停留在死记硬背的…

MMDetection代码实战

title: mmdet代码实战 date: 2023-06-10 17:01:45 tags: [detection,pytorch] MMDetection代码实战 这一届主要讲解了,如何构建cfg,如何在目标检测上设置自己的配置文件。主要的思维导图如下 [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下…

第3章“程序的机器级表示”:对齐(alignment)

许多计算机系统对基本数据类型的可允许地址做出了一些限制,要求某种类型的对象的地址必须是某个值 k k k (通常是2、4 或 8)的倍数。这种 对齐限制 简化了处理器和存储器系统之间接口的硬件设计。例如,假设一个处理器总是从存储器…

pikachu靶场-File Inclusion

文件包含漏洞概述 在web后台开发中&#xff0c;程序员往往为了提高效率以及让代码看起来更加简介&#xff0c;会使用”包含“函数功能。比如把一系列功能函数都写进function.php中&#xff0c;之后当某个文件需要调用的时候就直接在文件头上写上一句<?php include functio…

多叉树的构建,条件查询,修改删除节点

多叉树的构建查询&#xff0c;新增&#xff0c;修改&#xff0c;删除 文章目录 多叉树的构建查询&#xff0c;新增&#xff0c;修改&#xff0c;删除一&#xff0c;数据库表设计二、新增相对应数据库表的实体类三、新建多叉树树工具类四、多叉树树的条件查询五、多叉树的节点新…

关于【Git】push失败与使用小乌龟(TortoiseGit)时的一些报错解决方案

1.报错:No supported authentication methods available (server sent: publickey) 原因.小乌龟没有设置git路径&#xff0c;解决如下 将红框标注的地址改为自己的git安装地址即可。 2.使用git推送到远程仓库的时候报错Failed to connect to 127.0.0.1 port 7890: 拒绝连接 …

C# 让程序代码在固定的线程里运行

一、概述 在平时我们的开发中&#xff0c;多线程也是经常用到的&#xff0c;尤其是我们做上位机行业的&#xff0c;平时更是必不可少&#xff0c;在以前我做 Unity3d 开发时&#xff0c;其实并不用关心线程的问题&#xff0c;在 Unity 的开发中&#xff0c;所有代码基本都是单…

点云综述(整理自网络资源)

目录 一、什么是点云 二、如何获取点云 1、三维激光扫描仪 2、双目相机 双目测距基本原理 视差图 双目测距的优点与难点 3、RGB-D相机 RGB-D什么意思 RGB-D相机的分类 RGBD相机的缺点&#xff1a; RGBD相机的优点 三、点云有哪些研究方向 1、基于点云的分类 2、基于…

华为OD机试真题 JavaScript 实现【IPv4地址转换成整数】【2023 B卷 100分】

一、题目描述 存在一种虚拟 IPv4 地址&#xff0c;由4小节组成&#xff0c;每节的范围为0~255&#xff0c;以#号间隔&#xff0c; 虚拟 IPv4 地址可以转换为一个32位的整数&#xff0c;例如&#xff1a; 128#0#255#255&#xff0c;转换为32位整数的结果为2147549183&#xff0…

【深入理解函数栈帧:探索函数调用的内部机制】

本章我们要介绍的不是数学中的函数&#xff0c;而是C语言中的函数哟&#xff01; 本章重点 了解汇编指令深刻理解函数调用过程 样例代码&#xff1a; #include <stdio.h> int MyAdd(int a, int b) {int c 0;c a b;return c; }int main() {int x 0xA;int y 0xB;int…

SpringCloud第二篇:Feign远程调用

思考&#xff1a;为啥要学Feign呢&#xff1f; 先来看我们以前利用RestTemplate发起远程调用的代码&#xff1a; String url "http://userservice/user/" order.getUserId(); User user restTemplate.getFor0bject(url,User.class);这里就有几个问题&#xff1a…

首届“设计·无尽谈”论坛完满收官 持续打造当代设计共同体

首届“设计无尽谈”论坛在京举行 5月16日&#xff0c;首届“设计无尽谈”论坛在北京举行&#xff0c;本次论坛以“漫谈当代空间精神”为主题&#xff0c;12位来自顶尖建筑设计领域的嘉宾和设计师到场&#xff0c;论坛以茶话会的形式进行&#xff0c;不受严格的议程和时间限制的…

计算机网络之网络层

四.网络层&#xff1a;数据平面 4.1 网络层概述 网络层被分解为两个相互作用的部分&#xff0c;即数据平面和控制平面。 数据平面决定到达路由器输入链路之一的数据报如何转发到该路由器的输出链路之一&#xff0c;转发方式有&#xff1a; 传统的IP转发&#xff1a;转发基于…

Nginx(一)介绍Nginx、正向代理和实现反向代理的两个实例

文章目录 一、Nginx介绍二、正向代理三、反向代理四、实例演示1、反向代理实例一&#xff08;反向代理&#xff0c;访问www.123.com&#xff09;2、反向代理实例二&#xff08;使用 nginx 反向代理&#xff0c;根据访问的路径跳转到不同端口的服务中&#xff09; 五、nginx之lo…

文件操作之文件下载(32)

下载和读取是差不多的情况 区分 文件被解析&#xff0c;我们称为文件包含漏洞 显示文件的源代码&#xff0c;我们称为文件读取漏洞 提示文件下载&#xff0c;我们称为文件下载漏洞 #文件下载 文件下载出现的原因&#xff0c;在任意代码里面出现下载性的功能性函数所导致的…

调用腾讯API实现人像分割

目录 1. 作者介绍2&#xff0e;腾讯云API人像分割2.1 人像分割接口描述2.2 请求参数介绍 3&#xff0e;代码实现3.1 获取SecretId和SecretKey3.2 人像分割代码调试3.3 完整代码3.4 实验结果 1. 作者介绍 岳泽昂&#xff0c;男&#xff0c;西安工程大学电子信息学院&#xff0c…

MySQL主从同步——主库已有的数据如何到从库

一、复制主库数据到从库 此步骤主要针对运行一段时间的主库&#xff0c;需要将历史数据导入到从库&#xff0c;保证主从强一致性。 主库锁表停止写操作 在主库MySQL命令行中执行 flush tables with read lock; 主库数据导出 将主库所在主机命令行下使用mysqldump命令导出…