React中 setState 是同步的还是异步的?调和阶段 setState 干了什么?

React中 setState 是同步的还是异步的

  • 1. React 的 setState 是异步的
  • 2. 为什么 setState 在合成事件和生命周期函数中是异步的
  • 3. 为什么 setState 在原生事件和定时器中是同步的
  • 4. 为什么要这样设计?
  • 调和阶段是什么
  • setState在调和阶段干了什么?
  • 总结:

1. React 的 setState 是异步的

在 React 中,setState 并不是立即更新组件的状态,而是被放入一个更新队列。React 会批量处理这些更新,以提高性能。这种更新行为在一些情况下是异步的,特别是在某些事件回调或生命周期函数中。

2. 为什么 setState 在合成事件和生命周期函数中是异步的

React 的合成事件(Synthetic Events)和生命周期方法(如 componentDidMount、componentDidUpdate)是与 React 的事件处理和渲染周期紧密相关的。当你在这些地方调用 setState 时,React 会将更新加入到事件循环的下一轮,这样做是为了批量更新。

批量更新:在一个事件处理或生命周期方法内,React 会将多个 setState 更新合并(或“批处理”),以减少重新渲染的次数。这有助于提升性能,避免因每次状态变更都重新渲染组件。

异步行为:为了支持批量更新,React 会将状态更新的操作排入队列,并异步执行。这意味着,在同一个事件回调内,setState 并不会立即生效。你无法在 setState 之后立即读取到更新后的状态。

举个例子:

handleClick() {this.setState({ count: this.state.count + 1 });console.log(this.state.count); // 这里输出的值是旧的,因为setState是异步的
}

React 会将状态更新的操作放到事件队列中,等事件处理完后再批量执行更新。这就意味着,this.state.count 在 console.log 时,仍然是更新前的值。

3. 为什么 setState 在原生事件和定时器中是同步的

在原生事件和定时器中,React 选择了同步更新状态。这是因为 React 的更新机制和原生事件及定时器的执行机制有所不同。

原生事件:当你在原生事件(如 click、keydown 等)中调用 setState 时,React 会同步执行更新。这是因为原生事件是浏览器的事件系统,不依赖于 React 的事件系统批处理机制,因此 React 会立即执行状态更新并重新渲染组件。

定时器:setTimeout 或 setInterval 等定时器回调函数也是同步的,因为它们是在 JavaScript 执行队列中排队的,React 在这些情况下也会直接处理状态更新。

举个例子:

handleClick() {setTimeout(() => {this.setState({ count: this.state.count + 1 });console.log(this.state.count); // 此时输出的是新的值}, 0);
}

在这个例子中,由于 setState 是在 setTimeout 回调中调用的,React 会在这个回调执行完之后立即同步更新状态并重新渲染。

4. 为什么要这样设计?

React 设计这种行为是为了优化性能。通过将 setState 更新合并、批量处理,React 能减少不必要的重新渲染,从而提高性能。在合成事件和生命周期方法中,React 能够在事件循环的下一轮批量更新所有状态,避免频繁渲染。

而在原生事件和定时器中,React 选择同步更新,是为了避免与浏览器的原生事件处理和定时器队列发生冲突。如果 setState 在这些场景中是异步的,可能会导致不符合预期的渲染行为。

调和阶段是什么

调和阶段是 React 渲染过程中,从旧的虚拟 DOM 到新的虚拟 DOM 的比较过程。React 会根据新状态或新属性重新计算出组件的虚拟 DOM 树,并与当前的虚拟 DOM 树进行对比,然后通过差异算法(也叫做Diffing 算法)来找到两者之间的差异,最终生成最小的更新策略,然后将更新应用到真实 DOM 上。

setState在调和阶段干了什么?

  • 调和阶段 是 React 更新流程中的一部分,负责比较旧的虚拟 DOM 和新的虚拟 DOM,计算出需要更新的最小差异,并将这些差异应用到真实 DOM 上。
  • setState 是触发更新的机制,通过异步更新和批处理,React 能高效地更新组件状态并重新渲染 UI。
  • setState 的工作原理和调和过程密切相关,setState 更新的状态最终通过调和过程影响虚拟 DOM 的变化,并应用到真实 DOM 上。

总结:

合成事件和生命周期函数中:setState 是异步的,React 会批量处理更新以提高性能。
原生事件和定时器中:setState 是同步的,React 会立即执行状态更新,以避免与原生事件的同步执行发生冲突。
这种设计主要是为了平衡性能和正确的行为,确保 React 在不同场景下都能高效、可预测地工作。

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

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

相关文章

RabbitMQ高可用

生产者确认 生产者确认就是:发送消息的人,要确保消息发送给了消息队列,分别是确保到了交换机,确保到了消息队列这两步。 1、在发送消息服务的application.yml中添加配置 spring:rabbitmq:publisher-confirm-type: correlated …

Redis的特性ubuntu进行安装

文章目录 1.六大特性1.1内存存储数据1.2可编程1.3可扩展1.4持久化1.5集群1.6高可用1.7速度快 2.具体应用场景(了解)3.Ubuntu安装Redis3.1安装指令3.2查看状态3.3查找配置文件3.4修改文件内容3.5重启服务器生效3.6安装客户端并进行检查 4.Redis客户端介绍…

本地音乐服务器(三)

6. 删除音乐模块设计 6.1 删除单个音乐 1. 请求响应设计 2. 开始实现 首先在musicmapper新增操作 Music findMusicById(int id);int deleteMusicById(int musicId); 其次新增相对应的.xml代码&#xff1a; <select id"findMusicById" resultType"com.exa…

leetcode【滑动窗口】相关题目分析讲解:leetcode209,leetcode904

经典滑动窗口(leetcode209) 题干 题目难度&#xff1a;简单 题目分析 要求找到符合大于等于target的长度最小的子数组的常规思路便是暴力破解——遍历数组&#xff0c;通过两层遍历&#xff0c;找到最小的子数组并返回。 但显而易见&#xff0c;这样时间复杂度会是O(n2)级…

ArkTS组件结构和状态管理

1. 认识基本的组件结构 ArkTS通过装饰器Component 和Entry 装饰 struct 关键字声明的数据结构&#xff0c;构成一个自定义组件 自定义组件中提供了一个build函数&#xff0c;开发者需要在函数内以链式调用的方式进行基本的UI描述&#xff0c;UI描述的方法请参考UI描述规范srtuc…

语义分割(semantic segmentation)

语义分割(semantic segmentation) 文章目录 语义分割(semantic segmentation)图像分割和实例分割代码实现 语义分割指将图片中的每个像素分类到对应的类别&#xff0c;语义区域的标注和预测是 像素级的&#xff0c;语义分割标注的像素级的边界框显然更加精细。应用&#xff1a…

【STM32】在 STM32 USB 设备库添加新的设备类

说实话&#xff0c;我非常想吐槽 STM32 的 USB device library&#xff0c;总感觉很混乱。 USB Device library architecture 根据架构图&#xff1a; Adding a custom class 如果你想添加新的设备类&#xff0c;必须修改的文件有 usbd_desc.cusbd_conf.cusb_device.c 需要…

【母线槽分类与选型】

母线槽是一种高效、安全、节能的输电设备&#xff0c;广泛应用于各类建筑和工业领域。母线槽可以根据不同的分类方式进行划分&#xff0c;例如根据其结构、用途、导体材质等。母线槽以铜或铝作为导体、用非烯性绝缘支撑&#xff0c;然后装到金属槽中而形成的新型导体。在高层建…

一些任务调度的概念杂谈

任务调度 1.什么是调度任务 依赖&#xff1a;依赖管理是整个DAG调度的核心。调度依赖包括依赖策略和依赖区间。 依赖分为任务依赖和作业依赖&#xff0c;任务依赖是DAG任务本身的依赖关系&#xff0c;作业依赖是根据任务依赖每天的作业产生的。两者在数据存储模型上有所不同…

Unifying Top-down and Bottom-up Scanpath Prediction Using Transformers

Abstract 大多数视觉注意力模型旨在预测自上而下或自下而上的控制&#xff0c;这些控制通过不同的视觉搜索和自由观看任务进行研究。本文提出了人类注意力变换器&#xff08;Human Attention Transformer&#xff0c;HAT&#xff09;&#xff0c;这是一个能够预测两种形式注意力…

解决MindSpore-2.4-GPU版本的安装问题

问题背景 虽说在MindSpore-2.3之后的版本中不在正式的发行版中支持GPU硬件后端&#xff0c;但其实在开发分支版本中对GPU后端是有支持的&#xff1a; 但是在安装的过程中可能会遇到一些问题或者报错&#xff0c;这里复现一下我的Ubuntu-20.04环境下的安装过程。 Pip安装 基本的…

【拥抱AI】如何使用BERT等预训练模型计算语义相似度

使用BERT等预训练模型计算语义相似度是一种非常有效的方法&#xff0c;可以捕捉句子之间的深层次语义关系。下面是一个详细的步骤指南&#xff0c;介绍如何使用BERT和Sentence-BERT来计算语义相似度。 1. 环境准备 1.1 安装必要的库 首先&#xff0c;确保你已经安装了必要的…

Excel常用技巧分享

excel单元格内换行 直接按回车会退出当前单元格的编辑&#xff0c;如果需要在单元格中换行&#xff0c;需要按下AltEnter。 excel插入多行或多列 WPS 在WPS中想要插入多行&#xff0c;只需在右键菜单中输入对应的数字即可。 Office Excel excel中相对麻烦一些&#xff0c;比…

C# .NET环境下调用ONNX格式YOLOV8模型问题总结

我的环境是&#xff1a; Visual Studio: 2019 显卡&#xff1a; 一、遇到问题 1、EntryPointNotFoundException:无法在DLL“onnxruntime”中找到名为“OrtGetApiBase”的入口点。差了下原因&#xff0c;入口点是启动项中的问题。 原因&#xff1a;之前用yolov7时安装的版本在C…

【PTA】【数据库】【SQL命令】编程题1

数据库SQL命令测试题1 10-1 显示教工编号以02开头的教师信息 作者 冰冰 单位 广东东软学院 显示教工编号以02开头的教师信息 提示&#xff1a;请使用SELECT语句作答。 表结构: CREATE TABLE teacher ( TId CHAR(5) NOT NULL, -- 教师工号&#xff0c;主键 DId CHAR(2) …

VSCode快速生成vue组件模版

1&#xff0c;点击设置&#xff0c;找到代码片段 2&#xff0c;搜索vue&#xff0c;打开vue.json 3&#xff0c;添加模版 vue2模板 "vue2": {"prefix": "vue2","body": ["<template>"," <div>$0</di…

理解DOM:前端开发的基础

理解DOM 在前端开发中&#xff0c;DOM&#xff08;文档对象模型&#xff09;是一个至关重要的概念。它不仅定义了如何通过编程方式访问和修改网页内容&#xff0c;还为我们提供了一种结构化的方式来与页面交互。本文将带你了解DOM的基本概念、不同节点的操作以及何时可以进行更…

如何将几个音频合成一个音频?非常简单的几种合成方法

如何将几个音频合成一个音频&#xff1f;音频合成不仅仅是将不同的音频文件按顺序排列&#xff0c;它还可能涉及到音量调节、剪辑、淡入淡出、音效调整等多个方面。对于一些专业的音频制作人员来说&#xff0c;音频的每一部分细节都可能需要精心打磨&#xff0c;以确保最终合成…

虚拟化表格(Virtualized Table)性能优化

文章目录 功能介绍一开始的代码领导让我们分析一下开始优化如何监听事件和传参&#xff1f;定位操作栏更加优化 功能介绍 菜鸟最近做的一个功能如下&#xff1a; 后端返回两个很大的数组&#xff0c;例如&#xff1a;数组a 1w条&#xff0c;数组b 2w条&#xff0c;然后要操作b…

Orcad 输出有链接属性的PDF

安装adobe pdf安装Ghostscript修改C:\Cadence\SPB_16.6\tools\capture\tclscripts\capUtils\capPdfUtil.tcl ​ 设置默认打印机为 Adobe PDF ​ 将Ghostscript的路径修改正确 打开cadence Orcad &#xff0c;accessories->candece Tcl/Tk Utilities-> Utilities->PD…