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

深入理解 React 中 setState 的行为及状态更新时机

在 React 开发中,setState 是我们更新组件状态的核心 API。然而,setState 的行为因调用场景的不同而有所变化,这可能会让许多开发者感到困惑。特别是在 React 18 中,引入了自动批量更新机制,使得部分场景的行为发生了变化。本文将结合 React 17 和 React 18 的特性,对 setState 的行为和状态更新时机进行详细分析。


setState 的核心概念

在 React 中,setState 的调用通常不会立即更新组件的状态,而是将状态更新放入队列,等待合适的时机批量更新。这种设计的主要目的是提升性能,避免多次状态更新导致的多次渲染。

然而,在不同的调用场景中,setState 的表现可能有所不同。以下是常见的场景:


不同场景下 setState 的行为

1. React 合成事件处理函数

  • 行为:异步
  • 状态更新时机:批量更新

在 React 的合成事件中(如通过 onClick 等绑定的事件处理函数),setState 的调用是异步的。React 会将所有的 setState 调用收集起来,在当前事件循环结束后统一更新组件状态并触发重新渲染。

示例代码:
function App() {const [count, setCount] = React.useState(0);const handleClick = () => {setCount(count + 1);setCount(count + 2);console.log(count); // 输出的值是 0};return <button onClick={handleClick}>Click Me</button>;
}

原因setState 是异步的,console.log 中的 count 仍是更新前的值。


2. React 生命周期函数

  • 行为:异步
  • 状态更新时机:批量更新

在 React 的生命周期函数(如 componentDidMountuseEffect)中,setState 的调用同样是异步的,遵循批量更新的机制。

示例代码:
React.useEffect(() => {setCount(count + 1);setCount(count + 2);
}, []);

原因:生命周期函数中,React 会收集所有的 setState 调用,进行批量更新。


3. 原生 JavaScript 事件处理函数

  • React 17:

    • 行为:同步
    • 状态更新时机:立即更新
  • React 18:

    • 行为:异步
    • 状态更新时机:批量更新

在 React 17 中,由于原生事件不受 React 控制,setState 的调用是同步的,会立即更新状态。而在 React 18 中,自动批量更新机制扩展到了原生事件中,因此表现为异步批量更新。

示例代码:
document.getElementById('myButton').addEventListener('click', () => {setCount(count + 1);setCount(count + 2);console.log(count); // React 17 输出更新后的值;React 18 输出更新前的值
});

4. setTimeoutsetInterval 回调函数

  • React 17:

    • 行为:同步
    • 状态更新时机:立即更新
  • React 18:

    • 行为:异步
    • 状态更新时机:批量更新
示例代码:
setTimeout(() => {setCount(count + 1);setCount(count + 2);console.log(count); // React 17 输出更新后的值;React 18 输出更新前的值
}, 0);

5. Promisethen 回调函数

  • React 17:

    • 行为:同步
    • 状态更新时机:立即更新
  • React 18:

    • 行为:异步
    • 状态更新时机:批量更新
示例代码:
Promise.resolve().then(() => {setCount(count + 1);setCount(count + 2);console.log(count); // React 17 输出更新后的值;React 18 输出更新前的值
});

React 18 的自动批量更新机制

在 React 18 中,自动批量更新机制被扩展到了所有上下文中,包括:

  • 原生事件处理函数
  • setTimeoutsetInterval 回调函数
  • Promise.then 回调函数

示例代码:

setTimeout(() => {setCount(count + 1);setCount(count + 2);
}, 0);Promise.resolve().then(() => {setCount(count + 1);setCount(count + 2);
});console.log(count); // 在 React 18 中,状态更新是异步批量的,console.log 输出更新前的值

通过这一机制,React 在所有场景下的状态更新行为变得更加一致,从而减少了开发中的困惑。


总结

以下是不同场景下 setState 的行为及状态更新时机的总结表:

场景setState 行为状态更新时机
React 事件处理函数异步批量更新
生命周期函数异步批量更新
原生 JavaScript 事件处理函数异步(React 18+)批量更新
setTimeoutsetInterval 回调异步(React 18+)批量更新
Promisethen 回调函数异步(React 18+)批量更新

通过以上分析,我们可以清晰地理解 setState 在不同场景中的行为,并在实际开发中做出更合理的代码设计。如果你正在从 React 17 迁移到 React 18,务必要注意这些变化对代码逻辑的影响。

相关文章:

深入理解 React 中 setState 的行为及状态更新时机

在 React 开发中&#xff0c;setState 是我们更新组件状态的核心 API。然而&#xff0c;setState 的行为因调用场景的不同而有所变化&#xff0c;这可能会让许多开发者感到困惑。特别是在 React 18 中&#xff0c;引入了自动批量更新机制&#xff0c;使得部分场景的行为发生了变…...

一次完成Win10下MySQL 9.1 的安装

文章目录 前言一、 安装环境二、 安装方式选择三、下载四、安装 总结 前言 一、 安装环境 1、MySQL9.1.0.zip 下载地址&#xff1a;https://dev.mysql.com/downloads/mysql/ 2、Win10 3、客户端MySQL Workbench8.0 CE 下载地址&#xff1a;https://dev.mysql.com/downloads/w…...

有限元分析学习——Anasys Workbanch第一阶段笔记(8)水杯案例的对称与轴对称处理

目录 1 序言 2 对称处理 2.1 模型处理 2.2 网格划分、约束载荷及接触设置 2.3 计算结果 3 轴对称处理 3.1 对称与轴对称概念 3.2 轴对称问题的应用 3.2.1 创建分析案例 3.2.2 导入并处理模型 3.2.3 网格划分、约束载荷及接触设置 3.2.4 后处理计算结果 1 序言 本章…...

Vmware安装centos

用来记录自己安装的过程 一、创建虚拟机安装centos镜像 点击完成后&#xff0c;等待一会会进入centos的系统初始化界面 二、centos初始化配置 三、配置网络 1、虚拟网络编辑器&#xff0c;开启VMnet1、VMnet8的DHCP vmware左上角工具栏&#xff0c;点击【编辑】->【虚拟网…...

[Unity]MacOS下开发Unity

需要的插件 我使用的是vscode&#xff0c;经过长时间的使用我发现一个问题就是很多插件都是动态的在变化的&#xff0c;不是一成不变的&#xff0c;可能是重构&#xff0c;可能直接换了其他的工具。 所以这个插件也会是更新的状态。 2025年01月08日更新 .NET Install Tool …...

快手短剧播放器uniapp如何引入与对接?

uniApp前端微短剧项目开源分享 开源地址&#xff1a;git开源下载地址 文章目录 快手短剧播放器uniapp如何引入与对接&#xff1f;1.引入短剧播放器2.创建文件kscomponents组件3.local-stream.js文件说明4.用户行为事件4.local-stream.ksml文件参考如下 快手短剧播放器uniapp如何…...

Java 数据结构之-LinkedHashMap

继承关系和基本概念 LinkedHashMap是HashMap的子类&#xff0c;它继承了HashMap的基本功能。它在HashMap的基础上&#xff0c;通过维护一个双向链表来记录元素的插入顺序或者访问顺序&#xff08;可以通过构造函数指定&#xff09;&#xff0c;从而在遍历元素时能够按照特定的顺…...

记一次踩坑:json.Unmarshal() 解析数字类型

首先我们先明确下 json 包下 Unmarshal() 函数是什么&#xff1a; 它是 Go 语言标准库 encoding/json 中的一个函数&#xff0c;用于将 JSON 数据解析为 Go 语言中的数据结构。它的作用是将一个 JSON 格式的字节切片&#xff08;[]byte&#xff09;转换为对应的 Go 语言数据类…...

leetcode78.子集

给你一个整数数组 nums &#xff0c;数组中的元素 互不相同 。返回该数组所有可能的子集&#xff08;幂集&#xff09;。解集 不能 包含重复的子集。你可以按 任意顺序 返回解集。 示例 1&#xff1a; 输入&#xff1a;nums [1,2,3] 输出&#xff1a;[[],[1],[2],[1,2],[3],…...

docker学习记录:创建mongodb副本集

目的&#xff0c;是创建三个&#xff0c;避免出现错误时&#xff0c;仍然能正常工作。 要在 Docker 中创建一个 MongoDB 集群&#xff08;副本集&#xff09;&#xff0c;并确保数据存储在本地&#xff0c;同时允许局域网访问&#xff0c;你可以按照以下步骤进行操作。我们将创…...

JAVA学习-练习试用Java实现“从用户输入获取一个字符串,并使用split方法将其拆分为单词数组,然后打印出所有单词”

问题&#xff1a; 创建一个Java程序&#xff0c;从用户输入获取一个字符串&#xff0c;并使用split方法将其拆分为单词数组&#xff0c;然后打印出所有单词。 解答思路&#xff1a; 以下是一个Java程序&#xff0c;它从用户输入获取一个字符串&#xff0c;并使用 split 方法…...

网络安全 | 数据隐私保护:全球趋势与合规要求

网络安全 | 数据隐私保护&#xff1a;全球趋势与合规要求 一、前言二、全球数据隐私保护的主要趋势2.1 法律法规的强化2.2 消费者意识的觉醒2.3 技术创新推动隐私保护升级 三、不同国家和地区的数据隐私法规3.1 欧盟《通用数据保护条例》&#xff08;GDPR&#xff09;3.2 美国《…...

2025年度流行色揭晓:温暖舒适的摩卡慕斯

近日&#xff0c;全球色彩权威机构Pantone公布了2025年度流行色——PANTONE 17-1230 Mocha Mousse (摩卡慕斯)。这是一种温暖的柔和棕色&#xff0c;蕴含着内在的丰富质感&#xff0c;让人联想到可可、巧克力和咖啡的美味质量&#xff0c;满足我们对舒适和简单愉悦的渴望。 Pan…...

el-table拖拽表格

1、拖拽插件安装 npm i -S vuedraggable // vuedraggable依赖Sortable.js&#xff0c;我们可以直接引入Sortable使用Sortable的特性。 // vuedraggable是Sortable的一种加强&#xff0c;实现组件化的思想&#xff0c;可以结合Vue&#xff0c;使用起来更方便。 2、引入拖拽函数…...

Oracle LiveLabs实验: Multitenant Advanced Capabilities

本文为Oracle LiveLabs中实验Multitenant Advanced Capabilities的过程记录。 本实验不提供云上的免费环境&#xff0c;需要利用你自己的OCI账号来创建环境。 实验环境是通过OCI中的Stack&#xff0c;也就是Terraform自动创建的。 Oracle Resource Manager (ORM) stack 文件…...

【大模型】百度千帆大模型对接LangChain使用详解

目录 一、前言 二、LangChain架构与核心组件 2.1 LangChain 核心架构 2.2 LangChain 核心组件 三、环境准备 3.1 前置准备 3.1.1 创建应用并获取apikey 3.1.2 开通付费功能 3.2 获取LangChain文档 3.3 安装LangChain依赖包 四、百度千帆大模型对接 LangChain 4.1 LL…...

Vue3(一)

1.Vue3概述 Vue3的API由Vue2的选项式API改为了组合式API。但是&#xff0c;也是Vue2中的选项式API也是兼容的。 2.创建Vue3项目 create-vue 是 Vue 官方新的脚手架工具&#xff0c;底层切换到了 vite。使用create-vue创建项目的步骤如下&#xff1a; 安装 create-vue npm i…...

php命名空间

什么是命名空间 从广义上来说&#xff0c;命名空间是一种封装事物的方法&#xff0c;在很多地方都可以见到这种抽象概念。 例如&#xff0c;在操作系统中目录用来将相关文件分组&#xff0c;对于目录中的文件来说&#xff0c;它就扮演了命名空间的角色。 具体举个例子&#xf…...

AI也会犯错

一、缘起 1.1 问题的发现 AI模型在处理数值比较问题时&#xff0c;出现了一个有趣的现象&#xff1a;当被问到“9.9”和“9.11”哪个更大时&#xff0c;一些AI模型给出了错误的答案&#xff0c;认为“9.9”大于“9.11”。这一问题最初是由 Riley Goodside 发现的&#xff0c;…...

Android NDK开发入门2之适应idm环境

环境搭建 Android NDK开发实战之环境搭建篇(so库,Gemini ai)-CSDN博客 初始配置 前面已经运行了一个简单的初始程序&#xff0c;现在我们来往初始程序添加类和函数&#xff0c;并成功运行的实验。 一级配置 第一层配置主要是cmake文件环境和一些编译选项。 build配置 可参…...

HTML-多媒体标签

除了图像&#xff0c;网页还可以放置视频和音频。 1.<video> <video>标签是一个块级元素&#xff0c;用于放置视频。如果浏览器支持加载的视频格式&#xff0c;就会显示一个播放器&#xff0c;否则显示<video>内部的子元素。 <video src"example.…...

[Linux]生产消费者模型

目录 一、生产消费者模型概念 1.概念 2.模块构成 3.协作机制 二、基于BlockingQueue的多CP问题 1.BlockQueue模块 2.Task任务模块 3.创建多线程以及整合模块 三、基于信号量的环形队列CP模型 1.POISX信号量接口 初始化信号量 PV操作 信号量销毁 2.模型简述 3.…...

从零用java实现 小红书 springboot vue uniapp (9)消息推送功能

前言 移动端演示 http://8.146.211.120:8081/#/ 前面的文章我们主要完成了个人资料修改 消息页优化 这篇文章我们讲解消息推送 推送页面 因为我们的推送消息都在一个页面 所以我们可以复用消息的websokcet推送 首先需要在 点赞表 收藏表 关注表 回复表 都添加未读字段 MESSAG…...

zookeeper监听机制(Watcher机制)

文章目录 引言I zookeeper监听机制Watcher机制实现分布式的通知功能触发事件种类Watcher的三个过程II watch机制特点一次性触发事件封装event异步发送先注册再触发常见的通知状态和事件类型III 应用案例(Kafka)Kafka的消息模型Kafka在Zookeeper中保存的元数据Kafka 基于Contr…...

企业开通部署 Azure OpenAI 流程:如何创建一个AI聊天机器人

由于众所周知的原因&#xff0c;国内没法直接调用 OpenAI 接口。 下面我将演示企业如何开通 Azure OpenAI 服务&#xff0c;以及如何使用 C# 调用 Azure OpenAI 接口创建一个 Console 应用程序并实现聊天机器人功能。 1开通 Azure OpenAI 服务 要开通 Azure OpenAI 服务&…...

【Linux基础指令】第一期

一、Linux的介绍 Linux是一个开源的操作系统&#xff0c;性能、稳定性、安全性方面上都是很优秀的&#xff0c;所以它一直是企业后端系统的首选。所以其图形化界面并不是Linux的必需品&#xff0c;所以我们避免不了要使用命令行的形式来使用Linux&#xff0c;也就离不开…...

使用 Rust 和 WASM 打造高性能 Web 应用

在现代 Web 开发中&#xff0c;前端性能是衡量用户体验的重要指标之一。随着 WebAssembly (WASM) 的崛起&#xff0c;它为开发者提供了一种在浏览器中运行高性能代码的方式。而 Rust&#xff0c;作为一门以性能和安全性著称的编程语言&#xff0c;与 WASM 的结合使得构建高效的…...

SQL Server中可以通过扩展事件来自动抓取阻塞

在SQL Server中可以通过扩展事件来自动抓取阻塞&#xff0c;以下是详细流程&#xff1a; 开启阻塞跟踪配置&#xff1a; • 执行以下SQL语句来启用相关配置&#xff1a; EXEC sp_configureshow advanced options, 1; RECONFIGURE; EXEC sp_configure blocked process thresh…...

无网络时自动切换备用网络环境

目录 背景目标为什么需要做自动网络切换网络切换手段 网络环境实现思路和代码部署脚本开机自动执行附录连接两个网络时的路由问题 背景 目标 学校实验室有两个网络环境&#xff0c;我电脑使用网线连接稳定但低速的网络A&#xff0c;使用WiFi连接高速但不稳定的网络B。因此&am…...

回顾2024年重磅AI发布汇总

2024年在人工智能领域出现了不少值得关注的发布和进展&#xff0c;以下是根据时间线索&#xff0c;对一些亮点突破进行了总结&#xff1a; 二月 Stability AI 宣布推出Stable Diffusion 3。 Google 升级了 Bard 中的人工智能聊天功能&#xff0c;基于新的Gemini Pro模型&…...

基类指针指向派生类对象,基类指针的首地址永远指向子类从基类继承的基类首地址

文章目录 基类指针指向派生类对象&#xff0c;基类指针的首地址永远指向子类从基类继承的基类起始地址。代码代码2 基类指针指向派生类对象&#xff0c;基类指针的首地址永远指向子类从基类继承的基类起始地址。 代码 #include <iostream> using namespace std;class b…...

Postman接口测试02|接口用例设计

目录 六、接口用例设计 1、接口测试的测试点&#xff08;测试维度&#xff09; 1️⃣功能测试 2️⃣性能测试 3️⃣安全测试 2、设计方法与思路 3、单接口测试用例 4、业务场景测试用例 1️⃣分析测试点 2️⃣添加员工 3️⃣查询员工、修改员工 4️⃣删除员工、查询…...

负载均衡服务器要怎么配置?

目录 一、概述&#xff1a; 二、硬件配置&#xff1a; 三、操作系统配置&#xff1a; 四、负载均衡软件&#xff1a; 五、网络配置&#xff1a; 六、软件安装步骤&#xff1a; 6.1 安装 Nginx 6.2 安装 LVS 6.3 安装 HAProxy 6.4 安装 Keepalived 一、概述&#xff1…...

技术速递|通过 .NET Aspire 使用本地 AI 模型

作者&#xff1a;Aaron Powell 排版&#xff1a;Alan Wang 使用本地 AI 模型是无需将资源部署到云中即可在自己的机器上进行实验的好方法。在本文中&#xff0c;我们将探讨如何使用 .NET Aspire 与 Ollama 来本地运行 AI 模型&#xff0c;同时利用 Microsoft.Extensions.AI 抽象…...

esp32开发笔记之一:esp32开发环境搭建vscode+ubuntu

最近想用esp32做一个物联网项目&#xff0c;踩坑N个终于有点心得&#xff0c;写下来避免和我一样的小白踩无谓的坑。 写在前面&#xff1a; 第一&#xff0c;大家一定要用linux系统作为编译工具&#xff0c;速度上是windows无法比的&#xff0c;不要因为不熟悉linux而选择win…...

vue el-table 数据变化后,高度渲染问题

场景&#xff1a;el-table设置了height属性&#xff0c;但是切换查询条件后再次点击查询重新获取data时&#xff0c;el-table渲染的高度会有问题&#xff0c;滚动区域变矮了。 解决办法&#xff1a;使用doLayout方法‌&#xff0c;在表格数据渲染后调用doLayout方法可以重新布局…...

unity学习15:预制体prefab

目录 1 创建多个gameobject 2 创建prefab 2.1 创建prefab &#xff08;类&#xff09; 2.2 prefab 是一个文件 2.3 prefab可以导出 3 创建prefab variant &#xff08;子类&#xff09; 3.1 除了创建多个独立的prefab&#xff0c; 还可以创建 prefab variant 3.2 他…...

Harbor 安装教程

一、安装 Docker 安装必要的一些系统工具 sudo yum install -y yum-utils device-mapper-persistent-data lvm2添加 Docker 软件源信息 sudo yum-config-manager --add-repo https://mirrors.aliyun.com/docker-ce/linux/centos/docker-ce.repo修改软件源配置 sudo sed -i sdow…...

HTML5 波动动画(Pulse Animation)详解

HTML5 波动动画&#xff08;Pulse Animation&#xff09;详解 波动动画是一种动态效果&#xff0c;使元素周期性地放大和缩小&#xff0c;给人一种脉动的感觉。以下是如何使用 CSS 和 HTML5 创建波动动画的详细说明。 1. 基本概念 波动动画&#xff1a;通过改变元素的大小来…...

【运维】如何检查电脑正常异常和关机日志? 1074正常关机或重启 6006正常关机 41非正常关机 6008异常关机

事件 ID 1074&#xff1a;正常关机或重启&#xff0c;由用户或程序请求触发。 事件 ID 6006&#xff1a;正常关机&#xff0c;表示系统已正确关闭。 事件 ID 41&#xff1a;非正常关机&#xff0c;可能是由于电源问题、硬件故障或系统崩溃导致。 事件 ID 6008&#xff1a;异常关…...

解决后端控制台报错Error updating database

数据库字段 对应实体类字段 private BigDecimal maths; private BigDecimal chinese; private BigDecimal english; 新增数据时后端控制台报错 Error updating database. Cause: com.mysql.cj.jdbc.exceptions.MysqlDataTruncation: Data truncation: Out of range value for…...

(2023|NIPS,LLaVA-Med,生物医学 VLM,GPT-4 生成自指导指令跟随数据集,数据对齐,指令调优)

LLaVA-Med: Training a Large Language-and-Vision Assistant for Biomedicine in One Day 目录 LLaVA-Med: Training a Large Language-and-Vision Assistant for Biomedicine in One Day 0. 摘要 1. 简介 2. 相关工作 3. 生物医学视觉指令数据 4. 将多模态对话模型适配…...

I2C学习笔记

前言 我一直不是特别喜欢读文档&#xff0c;习惯了通过视频学习&#xff0c;因为视频能更直观地展现信息&#xff0c;给人一种更生动、形象的感觉。然而&#xff0c;随着学习的内容逐渐增多&#xff0c;我发现并不是所有的知识点都能在视频中找到&#xff0c;或者视频中展示的…...

JetPack——ViewModel

前提阅读 JetPack——Lifecycle Jetpack——LiveData ViewModel是什么&#xff1f; ViewModel 类是一种业务逻辑或屏幕级状态容器。它用于将状态公开给界面&#xff0c;以及封装相关的业务逻辑。 它的主要优点是&#xff0c;它可以缓存状态&#xff0c;并可在配置更改后持久…...

【Java 学习】对象赋值的艺术:Java中clone方法的浅拷贝与深拷贝解析,教你如何在Java中实现完美复制

&#x1f4ac; 欢迎讨论&#xff1a;如对文章内容有疑问或见解&#xff0c;欢迎在评论区留言&#xff0c;我需要您的帮助&#xff01; &#x1f44d; 点赞、收藏与分享&#xff1a;如果这篇文章对您有所帮助&#xff0c;请不吝点赞、收藏或分享&#xff0c;谢谢您的支持&#x…...

【计算机网络】课程 实验四 配置快速生成树协议(RSTP)

实验四 配置快速生成树协议&#xff08;RSTP&#xff09; 一、实验目的 1&#xff0e;理解快速生成树协议RSTP的工作原理。 2&#xff0e;掌握如何在交换机上配置快速生成树。 二、实验分析与设计 【背景描述】 某学校为了开展计算机教学和网络办公&#xff0c;建立了一个计…...

SpringBootWeb案例-1(day10)

准备工作 需求 & 环境搭建 需求说明 环境搭建 步骤&#xff1a; 准备数据库表(dept、emp)创建 springboot 工程&#xff0c;引入对应的起步依赖&#xff08;web、mybatis、mysql 驱动、lombok&#xff09;配置文件 application.properties 中引入 mybatis 的配置信息&…...

攻防世界 Web_php_wrong_nginx_config

​ 打开题目地址&#xff0c;显示为登录页面。尝试用御剑扫描一下&#xff0c;发现了admin页面&#xff0c;点进去显示如下 点开控制台&#xff0c;发现如下 isLogin参数为0。尝试抓包并该islogin参数为1&#xff0c;返回依旧不变。 再扫描&#xff0c;发现robots.txt&#xff…...

【VUE+ElementUI】通过接口下载blob流文件设置全局Loading加载进度

下载Blob流文件&#xff0c;并以服务形式显示文件下载进度 1、下载接口 增加 config参数&#xff0c;并用...config将该属性加入到请求中&#xff1b; xxapi.js文件中设置downloadFile下载接口 // 下载文件 export function downloadFile(data, config) {return request({ur…...

行为树详解(6)——黑板模式

【动作节点数据共享】 行为树中需要的参数可以来自游戏中的各个模块&#xff0c;如果仅需从多个模块获取少量参数&#xff0c;那么可以直接在代码中调用其他模块的单例继而层层调用获取数据。 如果获取的参数量很大&#xff0c;从架构上看&#xff0c;我们需要通过加一个中间…...