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

深拷贝、浅拷贝 react的“不可变值”

知识获取源–晨哥(现实中的人 嘿嘿)
react中如果你想让一个值始终不变 或者说其他操作不影响该值 它只是作用初始化的时候

使用了浅拷贝–改变了初始值

会改变初始值(selectList1)
都指向同一个地址

  const selectList1 = { title: '大大', value: '1' };const [list1, setList1] = useState(selectList1);// 列表list1.title = 'xiaoxiao';list1.value = '2';console.log('list1', list1, 'selectList1', selectList1);

在这里插入图片描述

使用浅拷贝结合react–实现不可变

function handleUpdate (id, newName) {const newlist = list2.map((item) => {if (item.id === id) {return {...item,name: newName};}return item;});setList2(newlist);}console.log('startlist', startlist, 'list2', list2);const onFirstClick = () => {handleUpdate(2, 'xiaoming');}

在这里插入图片描述

使用深拷贝 -实现不可变

使用 JSON.parse(JSON.stringify(obj)) 的方式来复制对象

const selectList1 = { title: '大大', value: '1' };
const [list1, setList1] = useState(JSON.parse(JSON.stringify(selectList1)));
list1.title = 'xiaoxiao';
list1.value = '2';
console.log('list1', list1, 'selectList1', selectList1);

在这里插入图片描述

使用hook- 实现不可变

const selectList1 = { title: '大大', value: '1' };
const [list1, setList1] = useState(selectList1);// 列表useEffect(() => {const newList={ title: 'xiaoxiao', value: '2' }setList1(newList);}, []);
console.log('list1', list1, 'selectList1', selectList1);
//setList1会新建一个栈给list1赋予值 改变list1的值时 不改变selectList1的值

在这里插入图片描述
在 React 中,useState Hook 返回的数组中,第一个元素是状态变量,第二个元素是更新状态的函数。在这个例子中,我们使用了 useState Hook 来定义了一个名为 list1 的状态变量,并将 selectList1 赋值给 list1。

useState Hook 会在内部维护一个状态对象,每次更新状态时,都会创建一个新的状态对象,并用新的对象替换原来的对象。因此,使用 setList1 函数更新 list1 状态时,实际上是将原来的状态对象替换为一个新的状态对象。

当我们修改 list1 状态变量中的属性时,实际上是修改了状态对象的属性。由于 setList1 函数会创建一个新的状态对象,因此修改状态对象的属性并不会影响到 setList1 函数本身,也就是说,setList1 函数并没有进行深拷贝,而仅仅是替换了状态对象的引用,从而实现了对状态变量的更新。

React 的状态更新是异步的,也就是说,状态更新函数并不会立即更新状态变量的值,而是将更新请求加入到一个更新队列中,等到下一次渲染时才会执行状态更新操作。因此,在状态更新函数中使用状态变量的值时,可能会出现不一致的情况,需要特别注意。

需要注意的是,虽然在这个例子中我们可以通过修改状态变量的属性来实现状态更新,但是在 React 中并不推荐这种方式。如果状态变量是一个对象或数组等引用类型,应该使用不可变数据的方式来进行状态更新,以避免出现意外的修改和副作用。

下面介绍几种常用的不可变数据的方式:

在react中 如果不想改变初始值的话 建议使用hook方法进行深拷贝

使用展开运算符(Spread Operator)

  • 对象的例子:
const [state, setState] = useState({ count: 0, name: 'Tom' });function handleClick() {setState({...state,count: state.count + 1,});
}

在这个例子中,我们使用展开运算符 … 来创建一个新的对象,新对象包含了原对象的所有属性和方法,同时修改了 count 属性的值。由于我们使用了新的对象来更新状态变量,因此可以实现不可变数据。

  • 数组的例子:
const [list, setList] = useState(['a', 'b', 'c']);function handleAdd() {setList([...list, 'd']);
}function handleDelete(index) {setList([...list.slice(0, index), ...list.slice(index + 1)]);
}
  • 使用数组的 map() 方法

可以使用数组的 map() 方法来创建一个新的数组,从而实现不可变数据。

const [list, setList] = useState([{ id: 1, name: 'Tom' }, { id: 2, name: 'Jerry' }]);function handleUpdate(id, newName) {
cosnt newlist=list.map(item => {if (item.id === id) {return {...item,name: newName,};}return item;})setList(newlist);
}

不可变数据的方式来管理状态的优缺点

可以带来以下优点:
提高性能:由于不可变数据可以避免一些难以发现的错误,并且可以减少不必要的重渲染,从而提高程序的性能。

简化代码:不可变数据可以避免副作用和意外修改,从而简化了代码的编写和维护。
方便调试:不可变数据可以避免一些难以发现的错误,从而方便调试和测试。

不可变数据的方式也存在一些缺点:
需要额外的代码:不可变数据需要创建新的对象或数组,因此需要额外的代码来实现。

需要更多的内存:由于不可变数据需要创建新的对象或数组,因此需要更多的内存来存储。
使用不可变数据的方式来管理状态,其原理是每次对数据进行修改时,都会创建一个新的数据对象,而不是在原始数据上进行修改。这样可以避免在修改数据时意外修改了其他地方引用的相同数据,从而增加了程序的稳定性和可读性。

使用不可变数据的方式,可以通过浅拷贝和深拷贝两种方式来实现。浅拷贝指的是只复制对象或数组的一层属性,而深拷贝则是复制对象或数组的所有属性和方法。在 React 中,可以使用浅拷贝和深拷贝的方式来管理状态,具体的方法包括展开运算符、数组的 map() 方法和库函数等。

易懂的深拷贝和浅拷贝[文章链接]1(https://blog.csdn.net/m0_50785976/article/details/127666504?ops_request_misc=%257B%2522request%255Fid%2522%253A%2522170229913616800186535741%2522%252C%2522scm%2522%253A%252220140713.130102334…%2522%257D&request_id=170229913616800186535741&biz_id=0&utm_medium=distribute.pc_search_result.none-task-blog-2allsobaiduend~default-2-127666504-null-null.142%5Ev96%5Epc_search_result_base4&utm_term=%E5%89%8D%E7%AB%AF%20%E6%B7%B1%E6%8B%B7%E8%B4%9D%E5%92%8C%E6%B5%85%E6%8B%B7%E8%B4%9D&spm=1018.2226.3001.4187) 文章链接2

相关文章:

深拷贝、浅拷贝 react的“不可变值”

知识获取源–晨哥(现实中的人 嘿嘿) react中如果你想让一个值始终不变 或者说其他操作不影响该值 它只是作用初始化的时候 使用了浅拷贝–改变了初始值 会改变初始值(selectList1) 都指向同一个地址 const selectList1 { title: 大大, value: 1 };con…...

赛宁网安多领域亮相第三届网络空间内生安全发展大会

2023年12月8日,第三届网络空间内生安全发展大会在宁开幕。两院院士、杰出专家学者和知名企业家相聚南京,围绕数字经济新生态、网络安全新范式进行广泛研讨,为筑牢数字安全底座贡献智慧和力量。 大会围绕“一会、一赛、一展”举办了丰富多彩的…...

LintCode 123 · Word Search (DFS字符处理经典题!)

123 Word Search Algorithms Medium Description Given a 2D board and a string word, find if the string word exists in the grid. The string word can be constructed from letters of sequentially adjacent cell, where “adjacent” cells are those horizontally o…...

SpringCloud面试题——Sentinel

一:什么是Sentinel? Sentinel是一个面向分布式架构的轻量级服务保护框架,实现服务降级、服务熔断、服务限流等功能 二:什么是服务降级? 比如当某个服务繁忙,不能让客户端的请求一直等待,应该立刻返回给客户端一个备…...

【精选】 VulnHub (超详细解题过程)

🍬 博主介绍👨‍🎓 博主介绍:大家好,我是 hacker-routing ,很高兴认识大家~ ✨主攻领域:【渗透领域】【应急响应】 【python】 【VulnHub靶场复现】【面试分析】 🎉点赞➕评论➕收藏…...

数据结构与算法-Rust 版读书笔记-2线性数据结构-队列

数据结构与算法-Rust 版读书笔记-2线性数据结构-队列 1、队列:先进先出 队列是项的有序集合,其中,添加新项的一端称为队尾,移除项的另一端称为队首。一个元素在从队尾进入队列后,就会一直向队首移动,直到…...

Android Kotlin Viewbinding封装

目录 Viewbinding配置 Activity封装 Activity使用 Fragment封装 Fragment使用 Dialog封装 Dialog使用 Viewbinding配置 android { viewBinding { enabled true } } Activity封装 import android.os.Bundle import android.view.LayoutInflater import androidx.ap…...

Flutter:web项目跨域问题解决

前后端解决系列 文章目录 一、Flutter web客户端解决本地环境调试跨域问题二、Flutter web客户端解决线上环境跨域问题 一、Flutter web客户端解决本地环境调试跨域问题 就一句命令【--web-browser-flag "--disable-web-security"】,用来屏蔽浏览器域名请…...

汽车标定技术(十二)--A2L文件生成的方法

目录 1.工具生成 1.1 CANape/ASAP2 Studio 1.2 ASAP2ToolKit 1.3 Matlab/Simulink 2.手写A2L要点 3.小结 A2L文件的制作一直以来是一个很少有人关注的方向,不管是标定工程师还是Slave协议栈的开...

《PySpark大数据分析实战》-03.了解Hive

📋 博主简介 💖 作者简介:大家好,我是wux_labs。😜 热衷于各种主流技术,热爱数据科学、机器学习、云计算、人工智能。 通过了TiDB数据库专员(PCTA)、TiDB数据库专家(PCTP…...

经验分享|MySQL分区实战(RANGE)

概述 分区概述 在 MySQL 中, InnoDB存储引擎长期以来一直支持表空间的概念。在 MySQL 8.0 中,同一个分区表的所有分区必须使用相同的存储引擎。但是,也可以为同一 MySQL 服务器甚至同一数据库中的不同分区表使用不同的存储引擎。 通俗地讲…...

Arrays.asList() 和 Collections.singletonList()

Arrays.asList() 和 Collections.singletonList() 概述 List 是我们使用Java时常用的集合类型。众所周知,我们可以轻松地在一行中初始化列表。例如,当我们想要初始化一个只有一个元素的List时,我们可以使用Arrays.asList(&#…...

Firmware Analysis Plus (Fap)固件模拟安装教程(最新)

最近在搞IoT的研究,但是难在设备比较难弄,只有固件,而没有设备,买吧,又太费钱,不划算。好在有很多项目可以在模拟环境中运行固件。但是几乎没有一个平台能够模拟所有硬件设备。IoT产品的架构也不尽相同。 …...

使用包、Crate 和模块管理项目(上)

目录 1、包和Crate 2、定义模块来控制作用域与私有性 2.1 在模块中对相关代码进行分组 3、引用模块项目的路径 3.1 使用 pub 关键字暴露路径 二进制和库 crate 包的最佳实践 3.2 super 开始的相对路径 3.3 创建公有的结构体和枚举 Rust 有许多功能可以让你管理代码的组…...

【Kotlin】

Lambda 就是一小段可以作为参数传递的代码。 因为正常情况下,我们向某个函数传参时只能传入变量,而借助Lambda 却允许传入一小段代码。 Lambda 表达式的语法结构: {参数名1: 参数类型, 参数名2: 参数类型 -> 函数体}首先,最外…...

JavaDay17

创建不可变集合 import java.util.Iterator; import java.util.List;public class Test {public static void main(String[] args) {/*创建不可变的List集合* "张三" "李四" "王五" "赵六*///一旦创建之后 是无法进行修改的 在下面的代码…...

Python爬取酷我音乐

🎈 博主:一只程序猿子 🎈 博客主页:一只程序猿子 博客主页 🎈 个人介绍:爱好(bushi)编程! 🎈 创作不易:喜欢的话麻烦您点个👍和⭐! 🎈…...

项目实战第四十七讲:易宝支付对接详解(保姆级教程)

易宝支付对接(保姆级教程) 为了实现项目的支付需求,公司选择了易宝支付进行对接,本文是项目实战第四十七讲,详解易宝支付对接。 文章目录 易宝支付对接(保姆级教程)1、需求背景2、流程图3、技术方案4、相关接口4.1、入驻相关(商户入网)4.2、账户相关接口(充值、提现、…...

python的websocket方法教程

WebSocket是一种网络通信协议,它在单个TCP连接上提供全双工的通信信道。在本篇文章中,我们将探讨如何在Python中使用WebSocket实现实时通信。 websockets是Python中最常用的网络库之一,也是websocket协议的Python实现。它不仅作为基础组件在…...

Qt处理焦点事件(获得焦点,失去焦点)

背景: 我只是想处理焦点动作,由于懒,上网一搜,排名靠前的一位朋友,使用重写部件的方式实现。还是因为懒,所以感觉复杂了。于是又花了一分钟解决了一下。 所以记录下来,以免以后忘了。 思路&a…...

SiteGround如何设置WordPress网站自动更新

SiteGround Autoupdate功能会自动帮我们更新在他们这里托管的所有WordPress网站,这样做是为了保证网站安全,并且让它们一直保持最新状态。他们会根据我们选择的设置自动更新不同版本的WordPress,包括主要版本和次要版本。在每次自动更新之前&…...

http代理和SOCK5代理谁更安全?

在这个网络化的时代,我们常常听到HTTP代理和SOCKS5代理这两个名词,不过很多人并不了解是什么意思。今天,我们将揭开这两种代理的神秘面纱,看看到底HTTP代理和SOCKS5代理哪个更安全? HTTP代理:高效通信的“枢…...

Kotlin关键字二——constructor和init

在关键字一——var和val中最后提到了构造函数,这里就学习下构造函数相关的关键字: constructor和init。 主要构造(primary constructor) kotlin和java一样,在定义类时就自动生成了无参构造 // 会生成默认的无参构造函数 class Person{ }与java不同的是…...

java的long类型超过9位报错:the literal 987654321000 of type int is out of range

java的long类型超过9位报错 1、报错提示2、报错截图3、解决办法4、参考文章 1、报错提示 the literal 987654321000 of type int is out of range 2、报错截图 3、解决办法 long类型是一种用于表示较大整数的数据类型,范围比int类型更广泛。然而,即使…...

【Java期末复习资料】(4)模拟卷

有不会的题可以后台问我的哦,看见了就会回。 本文章主要是模拟卷,知识点例题简答题已经发过了,可以在主页专栏Java中找一下 一、单项选择题 1. 编译 Java Application 源程序文件将产生相应的字节码文件,这些字节码文件的扩展名为…...

【计算机网络】UDP报文详解

目录 一. UDP协议概述 二. UDP报文格式 首部 三. UDP的缓冲区 一. UDP协议概述 UDP——用户数据报协议,是传输层的一个重要协议 基于UDP的应用层协议有:DNS,TFTP,SNMP,NTP 协议全称默认端口号DNSDomain Name Se…...

排序算法——归并排序

归并排序(Merge Sort)是计算机科学中非常重要的排序算法之一。它不仅高效、稳定,而且是许多高级排序技术和算法思想的基础。在本文中,我们将深入探讨归并排序的原理、实现方法,以及它的优缺点。 1. 归并排序的原理 归…...

2023 年安徽省职业院校技能大赛高职组“软件测试”赛项样题

2023 年安徽省职业院校技能大赛 高职组“软件测试”赛项样题 目录 任务一:功能测试(45 分) 1、测试计划(5 分) 2、测试用例(15 分) 3、Bug 清单(20 分) 4、测试报告&…...

Mysql8和Oracle实际项目中递归查询树形结构

背景: 项目升级,引入MySQL数据库,之前一直用的是Oracle数据,在做用户登录单位维护的时候,需要返回该用户所属单位下的所有子单位。下边是模拟项目数据实践的过程。 数据准备: 准备一张单位表&#xff0c…...

docker mysql8 设置不区分大小写

docker安装Mysql8.0的坑之lower_case_table_names_docker mysql lower_case_table_names-CSDN博客https://blog.csdn.net/p793049488/article/details/108365929 docker run ‐di ‐‐nametensquare_mysql ‐p 33306:3306 ‐e MYSQL_ROOT_PASSWORD123456 mysql...