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

【前端学习——react坑】useState使用

问题

使用useState 时,例如

const [selectedId, setSelectedId] = useState([false,true,false]);

这样直接利用,无法引发使用selectedId状态的组件的变化,但是selectedId是修改了的

 let temp=selectedId;temp[toggledId]=selectedId[toggledId]===false?true:false;setSelectedId(temp);

原因

一句话。let temp=selectedId;没有创建新的数组

这实际上是将 temp 设置为 selectedId 的引用,而不是一个新的数组。这意味着 temp 和 selectedId 共享相同的内存地址,它们指向相同的数组。所以,当你修改 temp 时,也会影响到 selectedId。

你直接修改了 selectedId 数组的值,React无法检测到setSelectedId前后状态的变化,因此不会触发 React 组件的重新渲染。

下面这个方法也不推荐,因为虽然 updatedSelectedId 这个数组是新的,但是其内部的元素本身与原数组 selectedId是相同的。因此,修改 updatedSelectedId[toggledId],其实是在修改原始的 selectedId对象。这样虽然会触发渲染,但是如果此时有另一个地方有着相同的初始 state,他们的 state 会被共享,也就是说你把本不该改变的状态也改变了。

  // 创建一个新的数组,保持不可变性const updatedSelectedId = [...selectedId];updatedSelectedId[toggledId] = !updatedSelectedId[toggledId];// 更新状态setSelectedId(updatedSelectedId);

解决

我们在更新state时要将state视为不可变的,你不应该使用类似于 arr[0] = ‘bird’ 这样的方式来重新分配数组中的元素,也不应该使用会直接修改原始数组的方法,例如 push() 和 pop()。可以通过使用像 filter() 和 map() 这样不会直接修改原始值的方法,从原始数组生成一个新的数组
在这里插入图片描述

其中数组展开运算符…还允许你把新添加的元素放在原始的 …artists 之。如此,展开操作就可以完成 push() 和 unshift() 的工作,将新元素添加到数组的末尾和开头。

因此这里我们通过map来产生新的数组

setMyList(selectedId.map((item,id)=> {if (id === toggledId) {return !item;} else {return item;}
}));

... 展开语法本质是是**“浅拷贝”——它只会复制一层**。这使得它的执行速度很快,但是也意味着当你想要更新一个嵌套属性时,你必须得多次使用展开语法。

为什么在 React 中不推荐直接修改 state?

在这里插入图片描述

更新 state 中的数组

即使你拷贝了数组,你还是不能直接修改其内部的元素。这是因为数组的拷贝是浅拷贝——新的数组中依然保留了与原始数组相同的元素。因此,如果你修改了拷贝数组内部的某个对象,其实你正在直接修改当前的 state。

const nextList = [...list];
nextList[0].seen = true; // 问题:直接修改了 list[0] 的值
setList(nextList);

nextList 和 list 是两个不同的数组,nextList[0] 和 list[0] 却指向了同一个对象。因此,通过改变 nextList[0].seen,list[0].seen 的值也被改变了。

解决:可以使用 map 在没有 mutation 的前提下将一个旧的元素替换成更新的版本。

setMyList(myList.map(artwork => {if (artwork.id === artworkId) {// 创建包含变更的*新*对象return { ...artwork, seen: nextSeen };} else {// 没有变更return artwork;}
}));
http://www.lryc.cn/news/357765.html

相关文章:

  • 【前端每日基础】day28——async/await
  • 错误记录:从把项目从Tomcat8.5.37转到Tomcat10.1.7
  • AJAX基础知识
  • xcode依赖包package已经安装,但是提示No such module ‘Alamofire‘解决办法
  • 基于Centos7 安装k8s一主两从
  • 基于java实现图片中任意封闭区域识别
  • 闭包是什么?有什么特性?对页面有什么影响?
  • MS Excel: 高亮当前行列 - 保持原有格式不被改变
  • langchain学习(十三)
  • 【Nginx】深入解析Nginx配置文件
  • 深入了解Nginx(一):Nginx核心原理
  • 产品经理-流程图结构图(四)
  • 15、Spring系统-AOP
  • 服务器感染了. rmallox勒索病毒,如何确保数据文件完整恢复?
  • [每日一练]按日期分组销售产品的最优解法
  • 免费wordpress中文主题
  • 单链表经典算法题理解
  • STM32的时钟介绍
  • FindBI学习总结
  • k8s——Pod详解
  • Visual Studio 的调试
  • mysql语句大全及用法
  • 如何找出真正的交易信号?Anzo Capital昂首资本总结7个
  • JavaScript-内存分配
  • 理论知识.质数打表
  • FFMPEG+ANativeWinodow渲染播放视频
  • 使用AXI MIG/Proc Sys Reset
  • Android基础-Kotlin语言的作用及优缺点
  • 手机投屏技巧:手机怎么投屏到电脑显示屏上?精选6招解决!
  • 内存函数<C语言>