setState详解

news/2024/11/25 5:31:09/

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

1.[partialState] :支持部分状态更改

this, setState({
x:100 //不论总共有多少状态,我们只修改了x,其余的状态不动
});

callback :在状态更改/视图更新完毕后触发执行,也可以说只要执行了setState, callback一定会执行

发生在componentDidUpdate周期函数之后 ,DidUpdate会在任何状态更改后都触发执行;而回调函数方式,可以在指定状态更新后处理一些事情;

2.特殊:
即便我们基于shouldComponentUpdate阻止了状态/视图的更新,DidUpdate周期函数肯定不会执行了,但是我们设置的这个
callback回调函数依然会被触发执行! !

类似于Vue框架中的$nextTick! !

在React18中,setState操作都是异步的「不论是在哪执行,例如:合成事件、周期函数、定时器…」

需要注意的是,React 可能会根据不同的情况使用不同的更新方式,而不一定会将所有的 setState 操作合并成一个更新操作。

3.目的:
实现状态的批处理「统一处理」

1.有效减少更新次数,降低性能消耗
2.有效管理代码执行的逻辑顺序

4.原理:
利用了更新队列updaters 机制来处理的

在当前相同的时间段内「浏览器此时可以处理的事情中」,遇到setState会 立即放入到更新队列中!此时状态/视图还未更新。当所有的代码操作结束,会“刷新队列”「通知更新队列中的任务执行」:把所有放入的setState合并在一起执行, 只触发一次视图更新 「批处理操作」


setState的两种方式:对象式和函数式对比

在这里插入图片描述

对象式最后x为20被优化成一次性更新没有中间状态!!!函数式是20,会有中间状态


对象式和函数式在实际项目中的例子

在 React 中,当你连续地进行多个 setState 操作时,React 会将这些操作合并起来,然后一次性地进行状态更新。这种行为被称为“对象方式的合并”。

例如,你连续调用了三次 setState 方法:

this.setState({ count: this.state.count + 1 });
this.setState({ count: this.state.count + 1 });
this.setState({ count: this.state.count + 1 });

如果使用的是对象方式更新状态,React 会将这三个对象合并成一个对象,然后进行一次性的状态更新,代码会被优化为:

this.setState({ count: this.state.count + 3 });

这种合并的行为,可以避免重复更新,提升 React 应用的性能。

但是,对于一些需要进行异步操作的场景,对象方式更新状态并不是一个好的选择。因为在异步操作中,合并并不总是起作用的。

举个例子

在进行网络请求时,你可能需要等待服务器返回数据,然后将返回的数据显示在页面上。如果你在网络请求代码块中使用对象方式更新状态,那么在请求还没有返回前,React 会将多个状态更新操作合并成一个更新操作,这可能会导致页面显示不正确或者渲染出错的问题。

因此,在这种场景下,使用函数方式更新状态是更好的选择。函数方式更新状态不会进行对象合并,而是将每次状态更新的操作包裹到一个更新函数中,然后将这个函数作为参数传递给 setState 方法。使用函数方式更新状态,可以避免对象方式进行状态合并时可能带来的问题。

在函数方式中,你可以使用当前状态和当前属性进行状态的更新。这样在状态更新的过程中不依赖于当前组件的状态,所以不会有状态合并的问题,而是针对当前状态进行更新。

如果你需要在网络请求后更新状态,可以这样写:

fetchData() {fetchDataFromServer().then((data) => {// 使用函数方式更新状态this.setState((prevState, props) => {// 基于先前状态进行更新const newData = processData(data);return {data: newData,};});});
}

在这个例子中,当网络请求成功后,React 不会合并 setState 操作,而是对于当前的状态使用新传入的函数进行更新。

总的来说,如果需要在异步操作中进行状态修改,并且避免状态合并带来的问题,你可以使用函数方式更新状态。

生活中的比喻

假设你正在建造一座大楼,楼房分为很多层,每层都将会有很多不同的物品放置。你已经规划好了第一层的布局,并且决定基于这个布局来规划其他的楼层。

现在假设你的朋友来参观你的大楼,他提议在第一层放置一个沙发,但是你已经决定好了第一层的布局,因此你无法加入新的物品。这就好比是在对象方式更新状态时,由于每次更新操作都会合并状态,所以在异步操作中可能会产生干扰,导致最终更新的状态并不是预期的状态。

但是如果你使用函数方式来更新状态,就好比是在楼房建造过程中,你会为每一层都规划出一个状态,然后基于这个状态去建造每一层,这样你的朋友提议在某一层加入一个沙发也不会对其他的层产生影响。因为你在每次更新状态时都会基于当前状态来执行更新操作,所以可以保证最终的状态更新会按照你的预期进行。


http://www.ppmy.cn/news/315434.html

相关文章

使用crictl pull时报错:“unknown service runtime.v1alpha2.ImageService”

如有错误,敬请谅解! 此文章仅为本人学习笔记,仅供参考,如有冒犯,请联系作者删除!! 引言: crictl 是 kubernetes cri-tools 的一部分,是专门为 kubernetes 使用 …

小米手机如何保存系统壁纸

原文地址:http://tieba.baidu.com/p/5732109130 1、先点击使用壁纸,随便应用于锁屏或者桌面即可; 2、打开:文件管理/手机,再点右上角设定显示隐藏文件; 3、找到MIUI/wallpaper这个目录点开,就…

微信小程序壁纸源码+自动采集小米图片

简介: 小程序内核里面对接的是小米壁纸,自动采集无需自己手动上传,而且可以搜索的内容很多​,各种类型的壁纸图片都是有的。 搭建方法: ​1,注册微信小程序,类目选工具_图片​。 2&#xff…

源壁纸微信小程序源码,自动采集小米壁纸自动更新

源码介绍: 接口调用小米主题的,源码内无加密,就一个小程序前端源码,无广告功能,搭建自用还可以。 修改教程: 修改project.config.json内的项目文件,然后直接通过微信开发者工具或者hbuilder打…

怎样更换vivoy31s锁屏壁纸

一个好看的锁频界面可以给我们带来好心情,其实vivo手机的锁屏壁纸都是可以更换的,vivoy31s手机功能强大。实用性高。可以自定义更换锁屏壁纸。今天来给大家示范一下如何更换。让我们一起来看看吧~ vivoy31s锁屏壁纸怎么更换 1、在手机上找到并打开【i主…

如何将小米画报中漂亮的壁纸保存下来?

小米画报是一款非常简洁而且没有捆绑的壁纸软件,我们在使用其设置我们个性的桌面的过程中,有时候常常会遇到这样的困惑:如何把好看的桌面图片保存下来呢?比如说: 虽然我们可以选择截图,但是截图带来的图片必…

LinuxC编程——高级文件操作

目录 一、查询文件信息1、stat2、stat fstat lstat区别 二、目录操作2.1 opendir2.2 readdir2.3 closedir例练习:实现ls操作 三、库3.1 库的定义3.2 库的分类3.2.1 静态库3.2.2 动态库 3.3 创建库3.3.1 静态库制作3.3.2 动态库制作 一、查询文件信息 1、stat int …

小米 MIUI 主题制作

原文链接: 小米 MIUI 主题制作 上一篇: typescript 基础例子 下一篇: js 使用jszip 将页面中的所有图片压缩为zip文件并下载 官网 https://mitheme.github.io/ https://github.com/mitheme/mitheme.github.io 下载编辑器 加压后直接运行 目前只支持v11 ... 比…