当前位置: 首页 > news >正文

setState详解

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.lryc.cn/news/92818.html

相关文章:

  • Qt5.12.6配置Android Arm开发环境(windows)
  • 七、进程程序替换
  • C++核心编程——详解运算符重载
  • 2023年前端面试汇总-CSS
  • Java调用Pytorch实现以图搜图(附源码)
  • 【EasyX】实时时钟
  • 基于XC7Z100的PCIe采集卡(GMSL FMC采集卡)
  • Kibana:使用 Kibana 自带数据进行可视化(一)
  • MySQL数据库基础 07
  • JVM | JVM垃圾回收
  • avive零头撸矿
  • openGauss5.0之学习环境 Docker安装
  • 数据可视化大屏人员停留系统的开发实录(默认加载条件筛选、单击加载、自动刷新加载、异步加载数据)
  • 【Linux】-关于调试器gdb的介绍和使用
  • 项目开发经验
  • STM32——05-按键、时钟控制、中断复位 点亮LED灯
  • VBA下载二进制文件,文本读写
  • MongoDB结合Robo 3T 1.4.3的简单操作
  • 【学习笔记】[AGC048D] Pocky Game
  • Qgis中进行Shp和Excel属性连接实现百强县公共预算空间分析
  • ES6 新增的循环方法
  • 移动端事件300ms延迟解决
  • NRF52832的DFU
  • 开源WebRTC库放大器模式在采集桌面图像时遇到的DPI缩放与内存泄漏问题排查
  • 敲黑板!java反射机制和原理
  • 【大数据工具】HBase 集群搭建与基本使用
  • 【Java】数组详解
  • NumPy库的学习
  • CentOS安装IRIS
  • 华为OD机试真题 JavaScript 实现【最多几个直角三角形】【2023Q1 100分】