【前端学习——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;
  }
}));

相关推荐

  1. react学习——29reactuseState使用

    2024-05-26 05:32:36       26 阅读
  2. React -- useState使用方法

    2024-05-26 05:32:36       45 阅读
  3. reactuseState 使用指南

    2024-05-26 05:32:36       31 阅读
  4. react使用useState更新数组失败

    2024-05-26 05:32:36       67 阅读
  5. React Hooks的useState、useRef使用

    2024-05-26 05:32:36       62 阅读

最近更新

  1. docker php8.1+nginx base 镜像 dockerfile 配置

    2024-05-26 05:32:36       94 阅读
  2. Could not load dynamic library ‘cudart64_100.dll‘

    2024-05-26 05:32:36       100 阅读
  3. 在Django里面运行非项目文件

    2024-05-26 05:32:36       82 阅读
  4. Python语言-面向对象

    2024-05-26 05:32:36       91 阅读

热门阅读

  1. 【vue嵌套iframe】实现项目重构

    2024-05-26 05:32:36       37 阅读
  2. glances的安装方式

    2024-05-26 05:32:36       30 阅读
  3. netstat命令检查端口是否监听

    2024-05-26 05:32:36       31 阅读
  4. C语言基础-如何避免内存泄漏

    2024-05-26 05:32:36       36 阅读
  5. 泛型中K T V E ? Object等分别代表的含义

    2024-05-26 05:32:36       30 阅读
  6. 所有笔记总结目录

    2024-05-26 05:32:36       28 阅读
  7. Python库之Scrapy的简介、安装、使用方法详细攻略

    2024-05-26 05:32:36       34 阅读
  8. 诺兰电影欣赏笔记

    2024-05-26 05:32:36       32 阅读
  9. Kafka之【消费消息】

    2024-05-26 05:32:36       28 阅读
  10. 解决uniApp 中不能直接使用 Axios 的问题

    2024-05-26 05:32:36       35 阅读
  11. 关系型数据库的三范式理解

    2024-05-26 05:32:36       38 阅读
  12. 汇编小程序

    2024-05-26 05:32:36       28 阅读
  13. 怎样使用类和对象

    2024-05-26 05:32:36       27 阅读
  14. CentOS配置应用服务自启动

    2024-05-26 05:32:36       28 阅读