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

react1816中的setState同步还是异步的深层分析

setState 是 react 中更新 UI 的唯一方法,其内部实现原理如下:

  1. 调用 setState 函数时,React 将传入的参数对象加入到组件的更新队列中。
  2. React 会调度一次更新(reconciliation),在调度过程中,React 会根据组件的 state 和 props 来计算出组件的新的状态,并比较新旧的状态,决定是否需要重新渲染组件。

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

  • particalState 是一个对象,支持部分修改 state,只更新当前要修改的属性,其余的保持不变。
  • callback 是可选的函数,在 setState 更新完成之后执行。类似于 vue 中的 nextTick 机制。
    • 发生在 componetDidUpdate 生命周期之后,DOM 更新完成之后。
    • componetDidUpdate 会在任何 state 更新之后调用,不管是否是 setState 引起的。
    • 这里的回调函数,只会在特定的 state 变化后出发,还要主动调用。
    • 即使我们使用了 shouldComponentUpdate返回 false 来组织组件更新, componentDidUpdate 不更新了,回调函数依然会执行。
import { Component } from "react";class ClassComp extends Component {state = {x: 10,y: 20,z: 0,};handleAdd = () => {// this是指向当前组件的实例,箭头函数式没有自己的thisthis.setState({x: this.state.x + 1,},() => {console.log(this.state.x, "xxxxxxxxxxxxx");});};shouldComponentUpdate() {return false;}componentDidUpdate() {console.log("componentDidUpdate class component");}render() {console.log("render class component");const { x, y, z } = this.state;return (<div>Class Component<p>x: {x}, y: {y} z:{z}<br /><button onClick={this.handleAdd}>add</button></p></div>);}
}
export default ClassComp;

在这里插入图片描述

setState 的同步与异步

  • r18 中,setState 在任何地方都是异步的,包括合成事件,周期函数,定时器。。。

    • r18 中有一套更新队列的机制,[updater]来处理的
    • 基于异步操作实现状态的批处理
  • 好处:

    • 异步的目的是为了性能优化,在多个 setState 调用时,可以合并成一个 state 更新

    • 异步的目的是为了防止 setState 调用过于频繁,造成性能问题

      在这里插入图片描述
      在这里插入图片描述
      在这里插入图片描述

  • 在 r18 之前。我们只在 react 的合成事件和生命周期函数中调用 setState 做批量更新,默认情况下,不会对原生事件,promise,setTimeout,requestAnimationFrame 等异步操作做批量更新。

r16 中的执行效果
在这里插入图片描述

r18 中的执行效果
在这里插入图片描述

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

需求

点击一个按钮,让数字 x 加一,结果为 30

import { Component } from "react";
class ClassComp extends Component {state = {x: 10,y: 20,z: 0,};handleAdd = () => {for (let i = 0; i < 20; i++) {this.setState(x:this.state.x+1);}console.log(this.state.x);};render() {console.log("render class component");const { x, y, z } = this.state;return (<div>Class Component<p>x: {x}, y: {y} z:{z}<br /><button onClick={this.handleAdd}>add</button></p></div>);}
}
export default ClassComp;

可以发现,打印结果为 1, 不是 30,改造代码,引入 flushSync
写法 1:

import { Component } from "react";
import { flushSync } from "react-dom";handleAdd = () => {for (let i = 0; i < 20; i++) {flushSync(() => {this.setState(x:this.state.x+1);}}console.log(this.state.x);};export default ClassComp;

写法 2:

import { Component } from "react";
import { flushSync } from "react-dom";handleAdd = () => {for (let i = 0; i < 20; i++) {this.setState(x:this.state.x+1);flushSync()}console.log(this.state.x);};export default ClassComp;

可以看到 render 执行了 20 次,但是打印结果为 30,如果只让 render 执行一次,打印结果为 30,需要改造代码

import { Component } from "react";
class ClassComp extends Component {state = {x: 10,y: 20,z: 0,};handleAdd = () => {for (let i = 0; i < 20; i++) {this.setState((prev) => {return { x: prev.x + 1 };});}console.log(this.state.x);};render() {console.log("render class component");const { x, y, z } = this.state;return (<div>Class Component<p>x: {x}, y: {y} z:{z}<br /><button onClick={this.handleAdd}>add</button></p></div>);}
}
export default ClassComp;

在这里插入图片描述

相关文章:

react1816中的setState同步还是异步的深层分析

setState 是 react 中更新 UI 的唯一方法&#xff0c;其内部实现原理如下&#xff1a; 调用 setState 函数时&#xff0c;React 将传入的参数对象加入到组件的更新队列中。React 会调度一次更新&#xff08;reconciliation&#xff09;&#xff0c;在调度过程中&#xff0c;Re…...

【UE5】将2D切片图渲染为体积纹理,最终实现使用RT实时绘制体积纹理【第七篇-体积纹理绘制】

我们前几篇已经完成了渲染部分&#xff0c;现在终于开始做动态绘制功能了 之前使用的是这样一个体积雾的切片图&#xff0c;那么现在要做的就是动态编辑它 首先&#xff0c;让我们简单了解一下它是如何运作的&#xff1a; 开始绘制画布以渲染目标&#xff0c;并将材质绘制到画…...

Linux的环境搭建

目录 1、linux的简单介绍 2、搭建linux环境 2.1 linux的环境安装 2.2 使用Xshell远程登入linux 2.2.1 Xshell免密登入 2.3 windows与Xshell与linux云服务器的关系 1、linux的简单介绍 linux操作系统 为 部分汇编 C语言编写 的操作系统 源代码公开(开源)&#xff0c;官…...

WPF+Mvvm案例实战(五)- 自定义雷达图实现

文章目录 1、项目准备1、创建文件2、用户控件库 2、功能实现1、用户控件库1、控件样式实现2、数据模型实现 2、应用程序代码实现1.UI层代码实现2、数据后台代码实现3、主界面菜单添加1、后台按钮方法改造&#xff1a;2、按钮添加&#xff1a;3、依赖注入 3、运行效果4、源代码获…...

网络爬虫-Python网络爬虫和C#网络爬虫

爬虫是一种从互联网抓取数据信息的自动化程序&#xff0c;通过 HTTP 协议向网站发送请求&#xff0c;获取网页内容&#xff0c;并通过分析网页内容来抓取和存储网页数据。爬虫可以在抓取过程中进行各种异常处理、错误重试等操作&#xff0c;确保爬取持续高效地运行 1、Python网…...

如何有效解除TikTok账号间的IP关联

在当今社交媒体环境中&#xff0c;TikTok凭借其独特的短视频形式吸引了数以亿计的用户。对许多内容创作者而言&#xff0c;运营多个账号是获取更大曝光和丰富内容的有效策略。然而&#xff0c;如何避免这些账号之间的IP关联&#xff0c;以防止被平台识别并封禁&#xff0c;成为…...

Python自省机制

Python 自省机制 Python 自省&#xff08;Introspection&#xff09;是一种动态检查对象的能力&#xff0c;使得开发者可以在运行时获取对象的相关信息&#xff0c;比如属性、方法、类型等。自省机制让 Python 具备了更强的动态性和灵活性&#xff0c;便于调试和开发。 自省&…...

wgan-gp 对连续变量 训练,6万条数据,训练结果不错,但是到局部的时候,拟合不好,是否可以对局部数据也进行计算呢

Wasserstein GAN with Gradient Penalty (WGAN-GP) 是一种改进的生成对抗网络&#xff08;GAN&#xff09;&#xff0c;它通过引入梯度惩罚来改进训练过程&#xff0c;从而提高生成模型的稳定性和质量。如果你在使用WGAN-GP对连续变量进行训练时&#xff0c;发现整体训练结果不…...

python 制作 发货单 (生成 html, pdf)

起因&#xff0c; 目的: 某个小店&#xff0c;想做个发货单。 过程: 先写一个 html 模板。准备数据&#xff0c; 一般是从数据库读取&#xff0c;也可以是 json 格式&#xff0c;或是 python 字典。总之&#xff0c;是数据内容。使用 jinja2 来渲染模板。最终的结果可以是 h…...

GeoWebCache1.26调用ArcGIS切片

常用网址&#xff1a; GeoServer GeoWebCache (osgeo.org) GeoServer 用户手册 — GeoServer 2.20.x 用户手册 一、版本需要适配&#xff1a;Geoserver与GeoWebCache、jdk等的版本适配对照 ​ 查看来源 二、准备工作 1、数据&#xff1a;Arcgis标准的切片&#xff0c;通过…...

深度学习-卷积神经网络-基于VGG16模型, 实现猫狗二分类(文末附带数据集下载链接, 长期有效)

简介: 1.基于VGG16模型进行特征提取, 结合mlp实现猫狗二分类 2.训练数据--"dog_cat_class\training_set" 3.模型训练流程 1.对图像数据进行导入和预处理 2.搭建模型, 导入VGG16模型, 去除mlp层, 将经过VGG16训练后的数据作为输入, 输入到自建的mlp层中进行训练, 要…...

计算Java集合占用的空间【详解】

以ArrayList为例&#xff0c;假设集合元素类型是Person类型&#xff0c;假设集合容量为10&#xff0c;目前有两个person对象{name:“Jack”,age12} {name:“Tom”,age14} public class Person{private String name;private int age; }估算Person对象占用的大小&#xff1a; 对…...

仕考网:关于中级经济师考试的介绍

中级经济师考试是一种职称考试&#xff0c;每年举办一次&#xff0c;报名时间在7-8月&#xff0c;考试时间在10-11月 报名入口&#xff1a;中guo人事考试网 报名条件&#xff1a; 1.高中毕业并取得初级经济专业技术资格&#xff0c;从事相关专业工作满10年; 2.具备大学专科…...

SYN590RL 300MHz至450MHz ASK接收机芯片IC

一般描述 SYN590RL是赛诺克全新开发设计的一款宽电压范围,低功耗,高性能,无需外置AGC电容&#xff0c;灵敏度达到典型-110dBm&#xff0c;300MHz”450MHz 频率范围应用的单芯片ASK或OOK射频接收器。 SYN59ORL是一款典型的即插即用型单片高集成度无线接收器&…...

15分钟学 Go 第 20 天:Go的错误处理

第20天&#xff1a;Go的错误处理 目标 学习如何处理错误&#xff0c;以确保Go程序的健壮性和可维护性。 1. 错误处理的重要性 在开发中&#xff0c;错误处理至关重要。程序在运行时可能会出现各种问题&#xff0c;例如文件未找到、网络连接失败等。正确的错误处理能帮助我们…...

C++——string的模拟实现(上)

目录 引言 成员变量 1.基本框架 成员函数 1.构造函数和析构函数 2.拷贝构造函数 3.容量操作函数 3.1 有效长度和容量大小 3.2 容量操作 3.3 访问操作 (1)operator[]函数 (2)iterator迭代器 3.4 修改操作 (1)push_back()和append() (2)operator函数 引言 在 C—…...

JavaCV 之均值滤波:图像降噪与模糊的权衡之道

&#x1f9d1; 博主简介&#xff1a;CSDN博客专家&#xff0c;历代文学网&#xff08;PC端可以访问&#xff1a;https://literature.sinhy.com/#/literature?__c1000&#xff0c;移动端可微信小程序搜索“历代文学”&#xff09;总架构师&#xff0c;15年工作经验&#xff0c;…...

桥接模式,外界与主机通,与虚拟机不通

一 二 在此选择Windows与外界连接的网卡&#xff0c;通过有线连就选有线网卡&#xff0c;通过无线连就选无线网卡。 三 如果需要设置固定IP&#xff0c;则选择"Manual"进行设置。我这边根据实际需要&#xff0c;走无线的时候用DHCP&#xff0c;走有线的时候设固定IP…...

用HTML构建酷炫的文件上传下载界面

1. 基础HTML结构 首先&#xff0c;我们构建一个基本的HTML结构&#xff0c;包括一个表单用于文件上传&#xff0c;以及一个列表用于展示已上传文件&#xff1a; HTML <!DOCTYPE html> <html> <head><title>酷炫文件上传下载</title><link …...

Gateway 统一网关

一、初识 Gateway 1. 为什么需要网关 我们所有的服务可以让任何请求访问&#xff0c;但有些业务不是对外公开的&#xff0c;这就需要用网关来统一替我们筛选请求&#xff0c;它就像是房间的一道门&#xff0c;想进入房间就必须经过门。而请求想要访问微服务&#xff0c;就必须…...

Ubuntu系统下交叉编译openssl

一、参考资料 OpenSSL&&libcurl库的交叉编译 - hesetone - 博客园 二、准备工作 1. 编译环境 宿主机&#xff1a;Ubuntu 20.04.6 LTSHost&#xff1a;ARM32位交叉编译器&#xff1a;arm-linux-gnueabihf-gcc-11.1.0 2. 设置交叉编译工具链 在交叉编译之前&#x…...

23-Oracle 23 ai 区块链表(Blockchain Table)

小伙伴有没有在金融强合规的领域中遇见&#xff0c;必须要保持数据不可变&#xff0c;管理员都无法修改和留痕的要求。比如医疗的电子病历中&#xff0c;影像检查检验结果不可篡改行的&#xff0c;药品追溯过程中数据只可插入无法删除的特性需求&#xff1b;登录日志、修改日志…...

解锁数据库简洁之道:FastAPI与SQLModel实战指南

在构建现代Web应用程序时&#xff0c;与数据库的交互无疑是核心环节。虽然传统的数据库操作方式&#xff08;如直接编写SQL语句与psycopg2交互&#xff09;赋予了我们精细的控制权&#xff0c;但在面对日益复杂的业务逻辑和快速迭代的需求时&#xff0c;这种方式的开发效率和可…...

MVC 数据库

MVC 数据库 引言 在软件开发领域,Model-View-Controller(MVC)是一种流行的软件架构模式,它将应用程序分为三个核心组件:模型(Model)、视图(View)和控制器(Controller)。这种模式有助于提高代码的可维护性和可扩展性。本文将深入探讨MVC架构与数据库之间的关系,以…...

Axios请求超时重发机制

Axios 超时重新请求实现方案 在 Axios 中实现超时重新请求可以通过以下几种方式&#xff1a; 1. 使用拦截器实现自动重试 import axios from axios;// 创建axios实例 const instance axios.create();// 设置超时时间 instance.defaults.timeout 5000;// 最大重试次数 cons…...

Unity | AmplifyShaderEditor插件基础(第七集:平面波动shader)

目录 一、&#x1f44b;&#x1f3fb;前言 二、&#x1f608;sinx波动的基本原理 三、&#x1f608;波动起来 1.sinx节点介绍 2.vertexPosition 3.集成Vector3 a.节点Append b.连起来 4.波动起来 a.波动的原理 b.时间节点 c.sinx的处理 四、&#x1f30a;波动优化…...

Netty从入门到进阶(二)

二、Netty入门 1. 概述 1.1 Netty是什么 Netty is an asynchronous event-driven network application framework for rapid development of maintainable high performance protocol servers & clients. Netty是一个异步的、基于事件驱动的网络应用框架&#xff0c;用于…...

RabbitMQ入门4.1.0版本(基于java、SpringBoot操作)

RabbitMQ 一、RabbitMQ概述 RabbitMQ RabbitMQ最初由LShift和CohesiveFT于2007年开发&#xff0c;后来由Pivotal Software Inc.&#xff08;现为VMware子公司&#xff09;接管。RabbitMQ 是一个开源的消息代理和队列服务器&#xff0c;用 Erlang 语言编写。广泛应用于各种分布…...

uniapp 字符包含的相关方法

在uniapp中&#xff0c;如果你想检查一个字符串是否包含另一个子字符串&#xff0c;你可以使用JavaScript中的includes()方法或者indexOf()方法。这两种方法都可以达到目的&#xff0c;但它们在处理方式和返回值上有所不同。 使用includes()方法 includes()方法用于判断一个字…...

uniapp 小程序 学习(一)

利用Hbuilder 创建项目 运行到内置浏览器看效果 下载微信小程序 安装到Hbuilder 下载地址 &#xff1a;开发者工具默认安装 设置服务端口号 在Hbuilder中设置微信小程序 配置 找到运行设置&#xff0c;将微信开发者工具放入到Hbuilder中&#xff0c; 打开后出现 如下 bug 解…...