setState是异步还是同步?

react中setState是同步还是异步困扰了好久,今天终于有了答案;它既是同步的,也是异步的;

批量更新:

加入我在页面上写三个setState去分别

componentDidMount() {this.setState({ val: this.state.val + 1 }) console.log(1)this.setState({ val: this.state.val + 1 }) console.log(2)this.setState({ val: this.state.val + 1 }) console.log(3)
}

 

在render中打印出的值是:3;这就说明setstate是同步的;
加入我想输入val值在执行其他+,可以使用setTimeout或者使用setstate的第二个参数callback;
setState 的时候react内部会创建一个 updateQueue ,通过 firstUpdatelastUpdatelastUpdate.next 去维护一个更新的队列,在最终的 performWork 中,相同的key会被覆盖
state = { val: 0 }
componentDidMount() {
setTimeout(_ => { this.setState({ val: this.state.val + 1 })console.log(this.state.val) // 输出更新后的值 --> 1 }, 0)
}

 

componentDidMount() { this.setState({ val: this.state.val + 1 }) console.log(this.state.val) // 输出的还是更新前的值 --> 0 }
其实还是和合成事件一样,当 componentDidmount 执行的时候,react内部并没有更新,执行完componentDidmount 后才去 commitUpdateQueue 更新。这就导致你在 componentDidmountsetState 完去console.log拿的结果还是更新前的值。
所以要在componentwillmount中更新state;
  • setState 只在合成事件和钩子函数中是“异步”的,在原生事件和 setTimeout 中都是同步的。
  • setState的“异步”并不是说内部由异步代码实现,其实本身执行的过程和代码都是同步的,只是合成事件和钩子函数的调用顺序在更新之前,导致在合成事件和钩子函数中没法立马拿到更新后的值,形式了所谓的“异步”,当然可以通过第二个参数 setState(partialState, callback) 中的callback拿到更新后的结果。
  • setState 的批量更新优化也是建立在“异步”(合成事件、钩子函数)之上的,在原生事件和setTimeout 中不会批量更新,在“异步”中如果对同一个值进行多次 setStatesetState 的批量更新策略会对其进行覆盖,取最后一次的执行,如果是同时 setState 多个不同的值,在更新时会对其进行合并批量更新。


链接:https://juejin.im/post/5b45c57c51882519790c7441

转载于:https://www.cnblogs.com/naniandongzhi/p/9813088.html

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

java学习(40):成员实例的定义和访问

定义一个student类 public class student { String name;//输入姓名 int age;//输入年龄 String address;//输入地址 char sex;//输入性别 double height;//输入身高 } 定义一个teststudent类 //成员实例的定义和访问 public class testStudent { public static void main(Stri…

简易计算器 java_终于写出一个简单的计算器了

该楼层疑似违规已被系统折叠 隐藏此楼查看此楼import javax.swing.*;import java.awt.event.*;import java.awt.*;import java.util.Scanner;//import java.util.Scanner;public class Jisuanji {JLabel JLabel1;JLabel JLabel2;JLabel JLabel3;//标签JFrame mainJFrame;//布局…

2018.10.20 NOIP模拟 蛋糕(线段树+贪心/lis)

传送门 听说是最长反链衍生出的对偶定理就能秒了。 本蒟蒻直接用线段树模拟维护的。 对于第一维排序。 维护第二维的偏序关系可以借助线段树/树状数组维护逆序对的思想建立权值线段树贪心求解。代码 转载于:https://www.cnblogs.com/ldxcaicai/p/10084858.html

java学习(41):成员实例的定义和访问续

定义一个studentstudy类 /1 使用Eclipse编写控制台应用程, 编写一个用来表示学生的java类, 并在类中定义描述学生特征的属性,姓名,年龄,性别,身高,体重和电话, 要求属性设置为私有访问级别并为私…

brew 安装 mysql5.7_Mac——brew替换源地址安装配置mysql@5.7版本

问题描述:使用brew方式安装mysql,存在以下问题:1.由于mysql已经升级到8.x版本,会默认安装8.x版本,会对之前部分特性不友好支持;2.brew默认安装源下载响应时间非常慢,下载时间过长容易超时&#…

ftp的本地用户搭建

前期的准备跟虚拟用户一样,就是配置文件不一样 修改配置文件 就是共享的都是自己的账号的家目录,然后启动服务就可以了 本地登陆的都是自己的账号密码 ftp本地的黑名单, 转载于:https://www.cnblogs.com/cash-su/p/9824553.html

java学习(42):巩固练习

定义一个testjava类 /*4 编写一个TestStudentOverrideConstructor.java类, 包含main方法,从控制台接收用户输入的学生信息,包括学生姓名,性别和年龄,使用带参数的构造器创建学生对象并将接收到的输入传递给这个构造器参…

错误解决:常出现在iis搭建网站

不能在此路径中使用此配置节。如果在父级别上锁定了该节,便会出现这种情况。锁定 在全新安装的IIS7下搭建网站,访问页面时出现错误信息如下: 配置错误 不能在此路径中使用此配置节。如果在父级别上锁定了该节,便会出现这种情况。锁定是默认…

java收发邮寄_JavaMail收发邮件的一般流程与主要方法

1、Properties属性类Properties p new Properties();p.put(key, value);key-| mail.smtp.host-| mail.smtp.port-| mail.smtp.auth->"true":"false"2、生成Authenticator的子类Overrideprotected PasswordAuthenticationgetPasswordAuthentication(){r…

Java中TreeMap和TreeSet的底层实现

TreeSet底层则采用NavigableMap这个接口来保存TreeSet集合&#xff0c;而实际上NavigableMap只是一个接口&#xff0c;实际上TreeSet还是用TreeMap来保存set元素。 TreeSet初始化的时候会new 一个TreeMap进行初始化&#xff1b; private transient NavigableMap<E,Object>…

oracle 11g数据库数据操作(亲测)

oracle 11g安装和oracle数据库监听配置就不说了&#xff0c;直接说数据库的相关操作 建立 wiicare 用户 create directory dump_dir as ‘d:\test\dump’; 使用 PLSQL Developer 连接数据库 登陆数据库&#xff0c;用户名:system 密码: 123456 连接为&#xff1a;sysdba 新建表…

使用mybatis操作AS400数据库

先简单说一下怎么使用【jt400.jar】连接AS400上的DB2数据库。 ※ jt400.jar资源&#xff0c;如果有安装AS400客户端的话&#xff0c;参考IBM官网 ※ http://www-01.ibm.com/support/docview.wss?uidswg21398042 安装目录下就有jt400.zip&#xff0c;改个后缀就能用了。 如果没…

java ajax 获取headers_Ajax获取Response头信息

$.ajax({type: HEAD, // 获取头信息&#xff0c;typeHEAD即可url : window.location.href,complete: function( xhr,data ){// 获取相关Http Response headervar wpoInfo {// 服务器端时间"date" : xhr.getResponseHeader(Date),// 如果开启了gzip&#xff0c;会返回…

oracle 数据操作的相关参数

ATTACH 连接到现有作业。 例如, ATTACHjob_name。 CONTENT 指定要加载的数据。 有效的关键字为: [ALL], DATA_ONLY 和 METADATA_ONLY。 DATA_OPTIONS 数据层选项标记。 有效的关键字为: SKIP_CONSTRAINT_ERRORS。 DIRECTORY 用于转储文件, 日志文件和 SQL 文件的目录对象。 …

【论文阅读】Deep Adversarial Subspace Clustering

导读&#xff1a; 本文为CVPR2018论文《Deep Adversarial Subspace Clustering》的阅读总结。目的是做聚类&#xff0c;方法是DASCDSC&#xff08;Deep Subspace Clustering&#xff09;GAN&#xff08;Generative Adversarial Networks&#xff09;。本文从以下四个方面来对论…

java 数据库连接池 开源_开源自己开发的一个JAVA数据库连接池,效果还算可以。...

该楼层疑似违规已被系统折叠 隐藏此楼查看此楼}public PreparedStatement prepareStatement(String sql, int[] columnIndexes)throws SQLException {return c.prepareStatement(sql, columnIndexes);}public PreparedStatement prepareStatement(String sql, String[] columnN…

Oracle数据库配置监听的作用

监听的作用就是给客户端电脑和中心数据库电脑建立数据的连接。一旦建立连接就不对两者造成任何影响&#xff0c;连接上的客户端上的用户可以做任何操作和查询&#xff0c;哪怕监听已经关闭或者被破坏。 注意&#xff1a;在数据库本机电脑连接数据库不需要用监听。哪怕没有监听…

java 值相同 hashcode_搞懂 Java equals 和 hashCode 方法

image搞懂 Java equals 和 hashCode 方法分析完 Java List 容器的源码后&#xff0c;本来想直接进入 Set 和 Map 容器的源码分析&#xff0c;但是对于这两种容器&#xff0c;内部存储元素的方式的都是以键值对相关的&#xff0c;而元素如何存放&#xff0c;便与 equals 和 hash…

Hadoop学习笔记

1.Hadoop安装 Apache的国内镜像地址&#xff1a; 地址1&#xff1a;http://mirror.bit.edu.cn/apache/ 地址2&#xff1a;https://mirrors.tuna.tsinghua.edu.cn/apache Fuck CSDN&#xff0c;谁给你的权利把开源的东西作为商品&#xff08;下载积分&#xff09;售卖&#xff1…

玩转oracle 11g(1):Oracle 11g的安装

由于工作需要&#xff0c;本人现在要对oracle 11g做一段攻坚战&#xff0c;先从安装开始 基本是傻瓜程序&#xff0c;网上也有大量教程 1 安装数据库软件 安装前准备工作 a.必须使用超级用户安装&#xff08;adminstrator&#xff09; b.服务器的名称不要有汉字 c.服务器的名称…