你理解的setState异步是对的吗?

简介: 你理解的setState异步是对的吗?

前言

在刚接触React时,我们开发用的最多的hook之一就是useState,使用它的返回值setState去更新数据时,就会发现,在有些情况下,数据并不是像预期中更新了,获取到的数据还是旧的数据。这就是为什么说setState是异步的。

但是这里初学者就有疑问了,怎么异步编程范畴里没有提到setState呢?你理解的异步真的是对的吗?

经历了React各个版本的更新,setState异步机制有什么变化呢?

入门篇

setState的使用

大家都知道setState接受一个参数,这个参数是newState值。这里再补充一些其它知识。

setState其实可以接收两个参数:

import React, { useState } from 'react';
const [state, setState] = useState(initState);
setState(newState, callback);
复制代码
  1. newState:最新值
  2. callback:异步更新之后的回调函数,即会在state更新之后执行

Tips: useState接收的initState是初始值,只会在mount时生效一次

为什么 setState 设计为异步?

import React, { useState } from 'react';
const [state, setState] = useState(false);
const changeState = ()=>{
    setState(true);
    console.log(state);   // 此处打印结果显示是:false,而不是true,表明这里setState是异步的
}
复制代码

针对这个问题,Dan在github上给出了回答:why is setState asynchronous?

这里给出总结:

  1. 保持一致性。如果同步更新了setState,但还未执行render函数,那么state和props无法保持一致性,从而引发很多问题。
  2. 批量更新,提升性能。

如果获取到setState异步更新之后的值?

1.利用setState第二个参数,callback

// setState第二个参数是一个回调函数,会在state更新后执行
this.setState({ massage: "你好" }, () => {
  console.log(this.state.message);
});
复制代码

2.componentDidUpdate 生命周期函数

进阶篇

异步的定义

在入门篇提到,setState是异步的,但这个异步不同于EventLoop里说的异步。

我们常说的Promise.then()、setTimeout是异步执行,然而setState从js执行上来说它是同步执行的。这里setState的异步是指调用setState之后state能否立即更新(即表现出来是异步的,本质是同步的)。

简而言之:setState是同步执行,异步更新

setState一定是异步的吗?

先说结论:

legacy模式下:在原生DOM事件和异步代码中,setState是同步的;在组件生命周期和React合成事件里,setState是异步的

concurrent模式下:都是异步

legacy 模式concurrent 模式傻傻分不清楚

legacy 模式是目前的主流模式,如今React18正式版已经发布,也就是说concurrent(并发)模式已经不再处于试验中,concurrent(并发)模式正式启用。

ReactDOM.render(<App />, rootNode)   // 通过这个方式创建应用,为 legacy 模式
复制代码
ReactDOM.unstable_createRoot(rootNode).render(<App />)   // 通过这个方式创建应用,为 concurrent 模式
复制代码

基于legacy模式

在React的setState函数实现中,会根据一个变量isBatchingUpdates判断是直接更新this.state还是放到队列中回头再说,而isBatchingUpdates默认是false,也就表示setState会同步更新this.state,但是,有一个函数batchedUpdates,这个函数会把isBatchingUpdates修改为true,而当React在调用事件处理函数之前就会调用这个batchedUpdates,造成的后果,就是由React控制的事件处理过程setState不会同步更新this.state**。

基于concurrent模式

React18正式版已经发布,concurrent(并发)模式正式启用。在这个模式下,setState都是异步的。

相关链接:

React 中 setState 什么时候是同步的,什么时候是异步的?



相关文章
|
6月前
|
Java 数据库连接 数据库
Java 组件详细使用方法与封装实战指南
本指南详解Java核心组件使用与封装技巧,涵盖跨平台开发、面向对象编程、多线程、数据库操作等关键内容,并提供工具类、连接池、异常及响应结果的封装方法。结合Spring框架、MyBatis、Spring Boot等主流技术,助你掌握高质量Java组件设计与开发实践。
217 2
|
9月前
|
调度 决策智能 知识图谱
腾讯云大模型知识引擎驱动 DeepSeek 满血版能源革命大模型:架构、优势与产业变革
腾讯云大模型知识引擎驱动的DeepSeek满血版能源革命大模型,融合了超大规模知识、极致计算效能和深度行业理解,具备智能预测、优化调度、设备健康管理和能源安全预警等七大功能模块。该模型通过分布式计算和多模态融合,提供精准的能源市场分析与决策支持,广泛应用于智慧风电场管理、油气田开发、能源市场交易等十大场景,助力能源行业的数字化转型与可持续发展。
|
存储 分布式计算 NoSQL
分布式数据库HBase的基本概念和架构之基本数据模型的Cell
HBase是一个分布式数据库系统,基于Google的Bigtable和Apache Hadoop的HDFS构建而成。它是一个分布式数据库的NoSQL数据库,主要用于存储和处理海量数据。HBase的核心特性包括高可用性、高性能和高伸缩性。在阿里云开发者社区中,我们将介绍HBase的基本概念和架构,以及它的基本数据模型Cell。
972 0
|
弹性计算 缓存 数据库
2核4G云服务器够用吗?能支持多少人?
阿里云2核4G服务器支持的在线人数受多种因素影响,如应用效率、并发数、内存、CPU性能、公网带宽、数据库及CDN/OSS使用等。应用程序类型与效率、并发连接数和内存使用是关键因素。199元/年的配置为ECS u1实例,适合初步需求。实际支持人数需综合评估上述因素并通过压力测试确定。
480 0
2核4G云服务器够用吗?能支持多少人?
|
消息中间件 JSON Cloud Native
Filebeat收集日志的那些事儿
云栖号资讯:【点击查看更多行业资讯】在这里您可以找到不同行业的第一手的上云资讯,还在等什么,快来! 【编者的话】最近因为云原生日志收集的需要,我们打算使用Filebeat作为容器日志收集工具,并对其进行二次开发,因此笔者将谈谈Filebeat收集日志的那些事儿。
Filebeat收集日志的那些事儿
|
jenkins Linux 持续交付
Docker(27)- docker push 命令详解
Docker(27)- docker push 命令详解
1195 0
Docker(27)- docker push 命令详解
官宣!支付宝小程序的 23 个入口大盘点
近日,支付宝小程序场景值文档发布。场景值用于描述用户进入小程序的路径,也就是说,场景值即代表了的小程序入口 。
4160 12
官宣!支付宝小程序的 23 个入口大盘点
|
存储 SQL 机器学习/深度学习
数仓中指标-标签,维度-度量,自然键-代理键等各名词解析及关系
作为一个数据人,是不是经常被各种名词围绕,是不是对其中很多概念认知模糊。有些词虽然只有一字之差,但是它们意思完全不同,今天我们就来了解下数仓建设及数据分析时常见的一些概念含义及它们之间的关系。
1091 0
数仓中指标-标签,维度-度量,自然键-代理键等各名词解析及关系
SAP MM 物料库存转固定资产业务操作以及相关财务凭证
SAP MM 物料库存转固定资产业务操作以及相关财务凭证
SAP MM 物料库存转固定资产业务操作以及相关财务凭证
|
SQL Oracle 网络协议
从零开始发布一个ArcGIS Server地图服务
从零开始发布一个ArcGIS Server地图服务
754 0
从零开始发布一个ArcGIS Server地图服务

热门文章

最新文章