this.setState的详细用法

2023-10-29

1.为什么不要直接对state进行赋值?

如果直接对this.state复制是不会去更新视图的,this.setState的原理是同一个队列来实现state的更新的,将需要更新的state放入到状态队列中,在一定时间段之后,合并并更新state,然后进行渲染.而直接对this.state赋值是不会有这些操作的,因此不要对state进行直接赋值.

2.this.setState为什么是异步的?

this.setState的操作是异步的,是为了提升性能对state的更新进行批量操作,官方文档中的原话:

将 setState() 视为请求而不是立即更新组件的命令。为了更好的感知性能,React 会延迟调用它,然后通过一次传递更新多个组件。React 并不会保证 state 的变更会立即生效。

如果每一次的调用this.setState都去更新state和渲染组件,这对浏览器来说是一个很大开销。因此就需要这种批量操作以达到性能的提升。

3.如果this.setState是异步的,那么在使用当前状态去更新下个状态的时候,由于当前的state可能不是最新的,就会出现问题;那怎么解决?

class Welcome2 extends React.Component{
    constructor(props) {
        super(props);
        this.state={a:1};
    }
    componentDidMount() {
        console.log(this.state);//a:1
        this.setState({a:this.state.a+1});
        console.log(this.state);//a:1
        this.setState({b:this.state.a});
        console.log(this.state);//a:1
    }

    render() {
        return <h1>{this.state.a}</h1>
    }
}

this.setState的第一个参数是可以接受一个函数的,在这个函数中第一个参数是state,第二个参数是props,其中state一定是最新的。

class Welcome2 extends React.Component{
    constructor(props) {
        super(props);
        this.state={a:1};
    }
    componentDidMount() {
        console.log(this.state,"a");//a:1  a
        this.setState((state)=>({
            a:state.a+1
        }));
        console.log(this.state,"b");//a:1  b
        this.setState((state)=>{
            console.log(this.state,state);//a:1  a:2 
            return {b:state.a}
        });
        console.log(this.state,"c");//a:1  c
    }

    render() {
        return <h1>{this.state.a} and {this.state.b}</h1>;//最终b也会被渲染到页面上
    }
}

4.在批量更新时,React 总会按照定义顺序进行浅合并。

this.setState({ a: 1 });
this.setState({ b: 2 });
this.setState({ c: 3, a: 'a' });

//最终结果:  a:a  b:2  c:3 

 看一下的代码最终输入多少?

class Welcome3 extends React.Component{
    constructor(props) {
        super(props);
        this.state={
            a:1,
            count:0
        };
    }
    componentDidMount() {
        const incrementChange = state => ({ count: state.count + 1 })
        this.setState(incrementChange)   //1
        this.setState(incrementChange)   //2
        this.setState({ count: this.state.count + 1 })   //3
        this.setState(incrementChange)   //4
    }

    render() {
        return <h1>{this.state.count}</h1>
    }
}

最终在页面渲染的是2。由于第一步和第二部采用传入的函数的方式进行更新状态,所以在第二步之后count 的值就是2,在第三步中,由于并没有渲染,因此当前this.state.count是0,在进行浅合并之后,第三步执行完之后,count的值为1,第四步中就是将count赋值成1+1为2,因此输出是2。由此我们可以知道,无论第三步前执行了多少次setState,在第三步赋值的时候this.state.count都是0,浅合并之后count的值都会是1,输出的结果也都是2。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

this.setState的详细用法 的相关文章

随机推荐

  • Setup&Hold互卡问题和Useful Skew的影响

    setup与hold timing互卡 conflict 现象的成因主要有哪些 如何解决 成因上来说 setup hold互卡主要有几种因素的影响 a 不同PVT条件下的cell delay variation较大 b 某些cell的lib
  • 小程序数据请求的方式和注意事项

    1 小程序中网络数据请求的限制 出于安全性方面的考虑 小程序官方对数据接口的请求做出了如下两个限制 只能请求HTTPS类型的接口 必须将接口的域名添加到信任列表中 2 配置request合法域名 假设要在自己的微信小程序中 希望请求某一域名
  • 怎么在网页或其他应用中打开你的app

    转载自 有改动 https segmentfault com a 1190000005967865 前言 对于一个完备的互联网产品而言需要有app端与web端两个不同前端 对于产品而言很多都希望能够将wap页上的用户引向native app
  • AndroidX设计架构MVVM之ViewModel生命周期分析

    本文基于ViewModel 2 1 0 先来一张ViewModel生命周期图 原文 AndroidX设计架构MVVM之ViewModel创建流程原理分析 AndroidX设计架构MVVM之ViewModel生命周期分析 AndroidX设计
  • ISCC SSTI

    先找参数吧 通过信息搜集 参数是xiaodouni 就是小豆泥的英文 这个是暹罗猫的一个名字吧 然后直接放两个payload的吧 看不懂的可以看一下我以前的文章CTFshow ssti里面讲了思路 这里就不再解释了 set pp dict
  • QT下配置Boost库

    QT下配置Boost库 前言 当使用别人的QT工程 复制到自己机器上 发现报如下错误 从QtCreator报错来看是找不到Boost相关文件和库 问题解决 首先去官网下载Boost库 编译boost库 下载boost源码 大家可以在boos
  • Ubuntu 18.04.6 单系统深度学习环境搭建(pytorch)

    1 系统安装 网上有很多这类教程 U盘制作 系统安装 2 显卡驱动安装 其他安装方法 ubuntu18 04安装显卡驱动 四种方式 我的安装方法 首先换清华源 选择一个附加驱动 然后应用更改 如果安装后重启黑屏 再尝试另外一个驱动 我是四个
  • R语言——方差分析

    一 方差分析的基本概念 方差分析是在20世纪20年代发展起来的一种统计方法 它是由英国统计学家费希尔在进行实验设计时为解释实验数据而首先引入的 从形式上看 方差分析是比较多个总体的均值是否相等 但是其本质上是研究变量之间的相互关系 方差分析
  • vue中使用echarts-liquidfill实现水球图

    先看效果图 echarts liquidfill查看官方文档 安装 npm install echarts save npm install echarts liquidfill save vue main js 中注册 import ec
  • postgresql从入门到菜鸟(十)initdb流程分析-环境设定

    分析完了参数解析 接下来分析环境设置 首先设定的是认证方式 static void check authmethod unspecified const char authmethod if authmethod NULL strlen a
  • 第三章网络传输介质

    一 信息 1 信号灯组成和类型 1 信号的组成 信息 定义数据类型 数据 描述事物的度量值 信号 信号时信息传输媒介 2 信息类型 数字信号 模拟信号 2 数字信号和模拟信号特点 1 数字信息 计算机通信使用 传输距离远 抗干扰能力强 通过
  • 如何定位CodeMirror插件

    CodeMirror插件不是普通的input textarea输入 无法使用selenium的input方法输入值 需要触发插件的事件才能真正实现值的更改 如何查看改插件有哪些事件 调用js触发setValue事件即可 document e
  • HDFS--读写测试

    读写测试 1 写测试 2 读测试 3 删除测试文件 1 写测试 cd export servers hadoop 2 6 0 cdh5 14 0 yarn jar share hadoop mapreduce hadoop mapreduc
  • 开发板BMP图片显示(6818开发板)

    BMP图片的前54个字节保存图片信息 不保存像素点 确认图片是不是BMP类型 读取整个图片大 pragma pack 1 typedef struct tagBITMAPFILEHEADER unsigned short bfType 2B
  • HR筛选简历内幕全解析

    我们已经把你的简历放进了公司的 人才库 在准备简历素材 挑选简历格式 着手创作简历的过程中 有一句话 可以用来作为戒条 Your resume is scanned not r ead YRIS 为什么让求职者以此为鉴呢 因为招聘者就是这样
  • 进程和线程的区别

    进程和线程的区别 1 进程和线程的关系和区别 2 线程的状态 3 进程的状态 4 多线程的实现方法 5 使用多线程的优缺点 6 线程的 run 和 start 有什么区别 7 什么是单线程和多线程 前两天面试 被问到进程和线程的区别 由于是
  • STM32F103 TFTLCD显示实验(一)

    文章内容 本文将介绍有关TFTLCD的有关知识 包括几个部分 分别如下 TFTLCD简介 相关指令 配置步骤 FSMC简介 由于篇幅过长 因此 代码讲解放到下一章中 链接如下 STM32F103 TFTLCD显示实验 二 https blo
  • 跑通官方的yolov7-tiny实验记录(yolov7-tiny可作为yolov5s的对比实验网络)

    目录 1 一些可用的参考链接 2 开始训练yolov7 2 1 weights 2 2 cfg 2 3 data 2 4 hyp 2 5 epochs 2 6 batch size 2 7 workers 2 8 name 1 一些可用的参
  • STM8中断的设置(ST Visual Develop和IAR环境下)

    以下以stm8s103为例介绍在ST Visual Develop和IAR环境下的中断设置 这两种只是环境不同其实中断向量是不会变的 先看一下数据手册 再结合芯片手册中中断向量映像表 如下图所示 结合起来的话我们就能够理解的 在用ST Vi
  • this.setState的详细用法

    1 为什么不要直接对state进行赋值 如果直接对this state复制是不会去更新视图的 this setState的原理是同一个队列来实现state的更新的 将需要更新的state放入到状态队列中 在一定时间段之后 合并并更新stat