首页 > 其他分享 >React学习笔记15-13-setState同步异步问题

React学习笔记15-13-setState同步异步问题

时间:2023-10-31 14:22:05浏览次数:35  
标签:count 异步 13 同步 15 dom React state setState

先说结论:

setState处在同步的逻辑中会异步更新状态,更新真实dom。 连续调用 setState 不会连续进行虚拟dom的对比和页面的更新 setState处在异步的逻辑中,同步更新状态,更新真实dom。  

1.同步状态

先看同步状态

/* eslint-disable react/no-direct-mutation-state */
import React, { Component } from 'react'

export default class App extends Component {
    state = {
        count: 1
    }
    render() {
        return (
            <div>  
                <div>{this.state.count}</div>
                <button onClick={
                    () => {
                      
                  
             this.setState({ count: this.state.count + 1 }) console.log(this.state.count) this.setState({ count: this.state.count + 1 }) console.log(this.state.count) this.setState({ count: this.state.count + 1 })

                    }
                
                }>add1</button>
          
            </div>
        )
    }
}

 可以看出来三个打印都是1,说明setState在同步环境下是异步进行更新的

 并且执行了三次setState实际上只更新了一次dom

这是因为

react会根据是同步队列还是异步队列来指定一个来决定setState是否合并处理的标志位,

同步队列为true, 这时setState会异步执行,进行合并处理, 因为跟新的都是同一个状态所以会 合并为 this.setState({ count: this.state.count + 1 }) 连续调用只会更新一次dom

2.同步状态下,如何获取dom更新后的state

/* eslint-disable react/no-direct-mutation-state */
import React, { Component } from 'react'

export default class App extends Component {
    state = {
        count: 1
    }
    render() {
        return (
            <div>
                <div>{this.state.count}</div>
                <button onClick={
                    () => {
                       
                        //  this.setState的第二个参数是一个函数,
                        //可以看做状态更新和dom后的回调
                        this.setState({
                            count: this.state.count + 1
                        }, () => {
                            console.log(this.state.count)
                        })

                        this.setState({
                            count: this.state.count + 1
                        }, () => {
                            console.log(this.state.count)
                        })
                        this.setState({
                            count: this.state.count + 3
                        }, () => {
                            console.log(this.state.count)
                        })
                        /*  同步逻辑下,在setState的回调中可以打印出更新后的状态。这里因为是
                            合并处理,所以以最后一个为准,打印出来是1+3 = 4
                        */


                    }
             
                }>add1</button>
             
            </div>
        )
    }
}

 如果在同步情况下想要获取dom更新后的state可以通过setState的第二个参数来获取

  this.setState的第二个参数是一个函数,可以看做状态更新和dom后的回调

 同步逻辑下,在setState的回调中可以打印出更新后的状态。这里因为是     合并处理,所以以最后一个为准,打印出来是1+3 = 4 3.异步状态
/* eslint-disable react/no-direct-mutation-state */
import React, { Component } from 'react'

export default class App extends Component {
    state = {
        count: 1
    }
    render() {
        return (
            <div>
                <div>{this.state.count}</div>
                <button onClick={
                    () => {
                        setTimeout(() => {
                            //异步逻辑
                            this.setState({
                                count: this.state.count + 1
                            })
                            console.log(this.state.count)
                            this.setState({
                                count: this.state.count + 1
                            })
                            console.log(this.state.count)
                            this.setState({
                                count: this.state.count + 1
                            })
                            console.log(this.state.count)
                        }, 0);
                    }
                }>add</button>
            </div>
        )
    }
}

 可以看到在异步状态下setState是同步调用的每次更新状态都会被打印下来,并且同步会更新状态和dom

标签:count,异步,13,同步,15,dom,React,state,setState
From: https://www.cnblogs.com/SadicZhou/p/17778760.html

相关文章

  • React Native 页面调试工具 react-native-vdebug
    yarnaddreact-native-vdebugimportReactfrom'react'import{createNativeStackNavigator}from'@react-navigation/native-stack'import{getRouter}from'./config'import{ErrorBoundary}from'../component/light......
  • React Native expo项目设置app顶部的状态栏
       importReactfrom'react'import{createNativeStackNavigator}from'@react-navigation/native-stack'import{getRouter}from'./config'import{ErrorBoundary}from'../component/light'importVDebug,{initT......
  • P1156 垃圾陷阱
    P1156垃圾陷阱考虑设计状态转移方程\(dp_{ij}=\;?\)本题一共有四个参数:物品、高度、生命值、时间,然后考虑如何定义\(i\)、\(j\)和\(dp_{ij}\)。于是可以按照垃圾的出现时间来排序,而物品作为第一维\(i\)表示考虑前\(i\)个垃圾。然后就剩下了[高度、生命值]两个值了,因......
  • 15、Linux日志审计
    Linux日志审计目录Linux日志审计1、日志文件的功能和分类2、日志文件保存位置和文件介绍3、管理日志服务的配置文件4、内核及系统日志5、日志消息的级别6、日志记录的一般格式7、用户日志分析8、程序日志分析9、日志服务器搭建10、补充1、日志文件的功能和分类日志的功能用于......
  • 102102151黄靖数据采集实践三
    作业一(1)要求:使用单线程和多线程的方法爬取中国气象网的限定数量的图片(2)下面给出代码实现:weather.pyimportscrapyfrom..itemsimportWeatherItemclassweatherSpider(scrapy.Spider):page=0number=0user_agent="Mozilla/5.0(WindowsNT10.0......
  • 彻底搞懂Reactor模型和Proactor模型
    在高性能的I/O设计中,有两个著名的模型:Reactor模型和Proactor模型,其中Reactor模型用于同步I/O,而Proactor模型运用于异步I/O操作。想要了解两种模型,需要了解一些IO、同步异步的基础知识,点击查看服务端的线程模型无论是Reactor模型还是Proactor模型,对于支持多连接的服务器,一般......
  • P4309 [TJOI2013] 最长上升子序列题解
    P4309[TJOI2013]最长上升子序列题解正文单调队列?单调锤子队列!!本题的操作可以省略成:单点修改区间查询好极了,此时我们有两种选择:线段树和树状数组,(平衡树,真不会,下一位因为不需要其他操作,所以我们还是选择更小巧更可爱的树状数组吧。关于vectorvector的insert操作支......
  • 使用react-native-drawer,跟着官网配置仍报错,Error: [Reanimated] `valueUnpacker` is
    在使用react-native-drawer组件时,编译项目报错试了许多的方法,最后通过在一篇博客中找到解决方法https://blog.csdn.net/lxyoucan/article/details/121851577因为在使用react-native-drawer时也需要使用react-native-reanimated,需要在babel.config.js增加如下第三行配置,然后重新......
  • AH6971-9V-15v电压升降12V2A芯片解决方案:参数特性和应用领域
    9V-15V升降12V2A芯片解决方案:参数特性和应用领域随着科技的发展,各种智能设备的需求在不断增长,而电源作为智能设备的重要组成部分,其稳定性和效率直接影响着设备的性能。在此背景下,9V-15V升降12V2A芯片解决方案应运而生。参数特性:宽输入电压范围:5V~35V,能够适应多种电源环境。高效......
  • Kaldi安装过程中遇到cub-1.8.0.tar.gz、sctk-20159b5.tar.gz、openfst-1.7.2.tar.gz三
    Kaldi安装过程中遇到cub-1.8.0.tar.gz、sctk-20159b5.tar.gz、openfst-1.7.2.tar.gz三个包下载不全产生报错的状况。从官网下载三个包,然后上传到Linux服务器kaldi/tools目录下,再运行Makefile即可。以下是三个包的下载链接cub-1.8.0.tar.gz下载链接:https://pan.baidu.com/s/1jX......