深圳住房和建设局网站登录东莞免费建站在线咨询

news/2025/9/23 23:22:24/文章来源:
深圳住房和建设局网站登录,东莞免费建站在线咨询,手机在线,网站建设公司市场定位参考文章 更新 state 中的数组 数组是另外一种可以存储在 state 中的 JavaScript 对象#xff0c;它虽然是可变的#xff0c;但是却应该被视为不可变。同对象一样#xff0c;当想要更新存储于 state 中的数组时#xff0c;需要创建一个新的数组#xff08;或者创建一份已…参考文章 更新 state 中的数组 数组是另外一种可以存储在 state 中的 JavaScript 对象它虽然是可变的但是却应该被视为不可变。同对象一样当想要更新存储于 state 中的数组时需要创建一个新的数组或者创建一份已有数组的拷贝值并使用新数组设置 state。 在没有 mutation 的前提下更新数组 在 JavaScript 中数组只是另一种对象。同对象一样需要将 React state 中的数组视为只读的。这意味着不应该使用类似于 arr[0] bird 这样的方式来重新分配数组中的元素也不应该使用会直接修改原始数组的方法例如 push() 和 pop()。 相反每次要更新一个数组时需要把一个新的数组传入 state 的 setting 方法中。为此可以通过使用像 filter() 和 map() 这样不会直接修改原始值的方法从原始数组生成一个新的数组。然后就可以将 state 设置为这个新生成的数组。 下面是常见数组操作的参考表。当操作 React state 中的数组时需要避免使用左列的方法而首选右列的方法 避免使用 (会改变原始数组)推荐使用 (会返回一个新数组添加元素pushunshiftconcat[...arr] 展开语法例子删除元素popshiftsplicefilterslice例子替换元素splicearr[i] ... 赋值map例子排序reversesort先将数组复制一份例子 或者可以使用 Immer 这样便可以使用表格中的所有方法了。 注意不幸的是虽然 slice 和 splice 的名字相似但作用却迥然不同 slice 可以拷贝数组或是数组的一部分。splice 会直接修改 原始数组插入或者删除元素。 在 React 中更多情况下会使用 slice因为不想改变 state 中的对象或数组。 向数组中添加元素 应该创建一个 新 数组其包含了原始数组的所有元素 以及 一个在末尾的新元素。这可以通过很多种方法实现最简单的一种就是使用 ... 数组展开 语法 setArtists( // 替换 state[ // 是通过传入一个新数组实现的...artists, // 新数组包含原数组的所有元素{ id: nextId, name: name } // 并在末尾添加了一个新的元素] );示例代码 import { useState } from react;let nextId 0;export default function List() {const [name, setName] useState();const [artists, setArtists] useState([]);return (h1振奋人心的雕塑家们/h1inputvalue{name}onChange{e setName(e.target.value)}/button onClick{() {setArtists([...artists,{ id: nextId, name: name }]);}}添加/buttonul{artists.map(artist (li key{artist.id}{artist.name}/li))}/ul/); }数组展开运算符还允许把新添加的元素放在原始的 ...artists 之前 setArtists([{ id: nextId, name: name },...artists // 将原数组中的元素放在末尾 ]);这样一来展开操作就可以完成 push() 和 unshift() 的工作将新元素添加到数组的末尾和开头。 从数组中删除元素 从数组中删除一个元素最简单的方法就是将它过滤出去。换句话说需要生成一个不包含该元素的新数组。这可以通过 filter 方法实现例如 import { useState } from react;let initialArtists [{ id: 0, name: Marta Colvin Andrade },{ id: 1, name: Lamidi Olonade Fakeye},{ id: 2, name: Louise Nevelson}, ];export default function List() {const [artists, setArtists] useState(initialArtists);return (h1振奋人心的雕塑家们/h1ul{artists.map(artist (li key{artist.id}{artist.name}{ }button onClick{() {setArtists(artists.filter(a a.id ! artist.id));}}删除/button/li))}/ul/); }点击“删除”按钮几次并且查看按钮处理点击事件的代码。 setArtists(artists.filter(a a.id ! artist.id) );这里artists.filter(s s.id ! artist.id) 表示“创建一个新的数组该数组由那些 ID 与 artists.id 不同的 artists 组成”。换句话说每个 artist 的“删除”按钮会把 那一个 artist 从原始数组中过滤掉并使用过滤后的数组再次进行渲染。注意filter 并不会改变原始数组。 转换数组 如果想改变数组中的某些或全部元素可以用 map() 创建一个新数组。传入 map 的函数决定了要根据每个元素的值或索引或二者都要对元素做何处理。 在下面的例子中一个数组记录了两个圆形和一个正方形的坐标。当点击按钮时仅有两个圆形会向下移动 100 像素。这是通过使用 map() 生成一个新数组实现的。 import { useState } from react;let initialShapes [{ id: 0, type: circle, x: 50, y: 100 },{ id: 1, type: square, x: 150, y: 100 },{ id: 2, type: circle, x: 250, y: 100 }, ];export default function ShapeEditor() {const [shapes, setShapes] useState(initialShapes);function handleClick() {const nextShapes shapes.map(shape {if (shape.type square) {// 不作改变return shape;} else {// 返回一个新的圆形位置在下方 50px 处return {...shape,y: shape.y 50,};}});// 使用新的数组进行重渲染setShapes(nextShapes);}return (button onClick{handleClick}所有圆形向下移动/button{shapes.map(shape (divkey{shape.id}style{{background: purple,position: absolute,left: shape.x,top: shape.y,borderRadius:shape.type circle? 50% : ,width: 20,height: 20,}} /))}/); }替换数组中的元素 想要替换数组中一个或多个元素是非常常见的。类似 arr[0] bird 这样的赋值语句会直接修改原始数组所以在这种情况下也应该使用 map。 要替换一个元素请使用 map 创建一个新数组。在 map 回调里第二个参数是元素的索引。使用索引来判断最终是返回原始的元素即回调的第一个参数还是替换成其他值 import { useState } from react;let initialCounters [0, 0, 0 ];export default function CounterList() {const [counters, setCounters] useState(initialCounters);function handleIncrementClick(index) {const nextCounters counters.map((c, i) {if (i index) {// 递增被点击的计数器数值return c 1;} else {// 其余部分不发生变化return c;}});setCounters(nextCounters);}return (ul{counters.map((counter, i) (li key{i}{counter}button onClick{() {handleIncrementClick(i);}}1/button/li))}/ul); }向数组中插入元素 有时也许想向数组特定位置插入一个元素这个位置既不在数组开头也不在末尾。为此可以将数组展开运算符 ... 和 slice() 方法一起使用。slice() 方法让从数组中切出“一片”。为了将元素插入数组需要先展开原数组在插入点之前的切片然后插入新元素最后展开原数组中剩下的部分。 下面的例子中插入按钮总是会将元素插入到数组中索引为 1 的位置。 import { useState } from react;let nextId 3; const initialArtists [{ id: 0, name: Marta Colvin Andrade },{ id: 1, name: Lamidi Olonade Fakeye},{ id: 2, name: Louise Nevelson}, ];export default function List() {const [name, setName] useState();const [artists, setArtists] useState(initialArtists);function handleClick() {const insertAt 1; // 可能是任何索引const nextArtists [// 插入点之前的元素...artists.slice(0, insertAt),// 新的元素{ id: nextId, name: name },// 插入点之后的元素...artists.slice(insertAt)];setArtists(nextArtists);setName();}return (h1振奋人心的雕塑家们/h1inputvalue{name}onChange{e setName(e.target.value)}/button onClick{handleClick}插入/buttonul{artists.map(artist (li key{artist.id}{artist.name}/li))}/ul/); }其他改变数组的情况 总会有一些事是仅仅依靠展开运算符和 map() 或者 filter() 等不会直接修改原值的方法所无法做到的。例如可能想翻转数组或是对数组排序。而 JavaScript 中的 reverse() 和 sort() 方法会改变原数组所以无法直接使用它们。 然而可以先拷贝这个数组再改变这个拷贝后的值。 例如 import { useState } from react;const initialList [{ id: 0, title: Big Bellies },{ id: 1, title: Lunar Landscape },{ id: 2, title: Terracotta Army }, ];export default function List() {const [list, setList] useState(initialList);function handleClick() {const nextList [...list];nextList.reverse();setList(nextList);}return (button onClick{handleClick}翻转/buttonul{list.map(artwork (li key{artwork.id}{artwork.title}/li))}/ul/); }在这段代码中先使用 [...list] 展开运算符创建了一份数组的拷贝值。当有了这个拷贝值后就可以使用像 nextList.reverse() 或 nextList.sort() 这样直接修改原数组的方法。甚至可以通过 nextList[0] something 这样的方式对数组中的特定元素进行赋值。 然而即使拷贝了数组还是不能直接修改其内部的元素。这是因为数组的拷贝是浅拷贝——新的数组中依然保留了与原始数组相同的元素。因此如果修改了拷贝数组内部的某个对象其实正在直接修改当前的 state。举个例子像下面的代码就会带来问题。 const nextList [...list]; nextList[0].seen true; // 问题直接修改了 list[0] 的值 setList(nextList);虽然 nextList 和 list 是两个不同的数组nextList[0] 和 list[0] 却指向了同一个对象。因此通过改变 nextList[0].seenlist[0].seen 的值也被改变了。这是一种 state 的 mutation 操作应该避免这么做可以用类似于 更新嵌套的 JavaScript 对象 的方式解决这个问题——拷贝想要修改的特定元素而不是直接修改它。下面是具体的操作。 更新数组内部的对象 对象并不是 真的 位于数组“内部”。可能他们在代码中看起来像是在数组“内部”但其实数组中的每个对象都是这个数组“指向”的一个存储于其它位置的值。这就是当在处理类似 list[0] 这样的嵌套字段时需要格外小心的原因。其他人的艺术品清单可能指向了数组的同一个元素 当更新一个嵌套的 state 时需要从想要更新的地方创建拷贝值一直这样直到顶层。 让我们看一下这该怎么做。 在下面的例子中两个不同的艺术品清单有着相同的初始 state。他们本应该互不影响但是因为一次 mutation他们的 state 被意外地共享了勾选一个清单中的事项会影响另外一个清单 import { useState } from react;let nextId 3; const initialList [{ id: 0, title: Big Bellies, seen: false },{ id: 1, title: Lunar Landscape, seen: false },{ id: 2, title: Terracotta Army, seen: true }, ];export default function BucketList() {const [myList, setMyList] useState(initialList);const [yourList, setYourList] useState(initialList);function handleToggleMyList(artworkId, nextSeen) {const myNextList [...myList];const artwork myNextList.find(a a.id artworkId);artwork.seen nextSeen;setMyList(myNextList);}function handleToggleYourList(artworkId, nextSeen) {const yourNextList [...yourList];const artwork yourNextList.find(a a.id artworkId);artwork.seen nextSeen;setYourList(yourNextList);}return (h1艺术愿望清单/h1h2我想看的艺术清单/h2ItemListartworks{myList}onToggle{handleToggleMyList} /h2你想看的艺术清单/h2ItemListartworks{yourList}onToggle{handleToggleYourList} //); }function ItemList({ artworks, onToggle }) {return (ul{artworks.map(artwork (li key{artwork.id}labelinputtypecheckboxchecked{artwork.seen}onChange{e {onToggle(artwork.id,e.target.checked);}}/{artwork.title}/label/li))}/ul); }问题出在下面这段代码中: const myNextList [...myList]; const artwork myNextList.find(a a.id artworkId); artwork.seen nextSeen; // 问题直接修改了已有的元素 setMyList(myNextList);虽然 myNextList 这个数组是新的但是其内部的元素本身与原数组 myList 是相同的。因此修改 artwork.seen其实是在修改原始的 artwork 对象。而这个 artwork 对象也被 yourList 使用这样就带来了 bug。这样的 bug 可能难以想到但好在如果避免直接修改 state它们就会消失。 可以使用 map 在没有 mutation 的前提下将一个旧的元素替换成更新的版本。 setMyList(myList.map(artwork {if (artwork.id artworkId) {// 创建包含变更的新对象return { ...artwork, seen: nextSeen };} else {// 没有变更return artwork;} }));此处的 ... 是一个对象展开语法被用来创建一个对象的拷贝. 通过这种方式没有任何现有的 state 中的元素会被改变bug 也就被修复了。 通常来讲应该只直接修改刚刚创建的对象。如果正在插入一个新的 artwork可以修改它但是如果想要改变的是 state 中已经存在的东西就需要先拷贝一份了。 使用 Immer 编写简洁的更新逻辑 在没有 mutation 的前提下更新嵌套数组可能会变得有点重复。就像对对象一样: 通常情况下应该不需要更新处于非常深层级的 state 。如果有此类需求或许需要调整一下数据的结构让数据变得扁平一些。如果想改变 state 的数据结构可以使用 Immer 它让你可以继续使用方便的但会直接修改原值的语法并负责为你生成拷贝值。 下面是我们用 Immer 来重写的艺术愿望清单的例子 import { useState } from react; import { useImmer } from use-immer;let nextId 3; const initialList [{ id: 0, title: Big Bellies, seen: false },{ id: 1, title: Lunar Landscape, seen: false },{ id: 2, title: Terracotta Army, seen: true }, ];export default function BucketList() {const [myList, updateMyList] useImmer(initialList);const [yourList, updateYourList] useImmer(initialList);function handleToggleMyList(id, nextSeen) {updateMyList(draft {const artwork draft.find(a a.id id);artwork.seen nextSeen;});}function handleToggleYourList(artworkId, nextSeen) {updateYourList(draft {const artwork draft.find(a a.id artworkId);artwork.seen nextSeen;});}return (h1艺术愿望清单/h1h2我想看的艺术清单/h2ItemListartworks{myList}onToggle{handleToggleMyList} /h2你想看的艺术清单/h2ItemListartworks{yourList}onToggle{handleToggleYourList} //); }function ItemList({ artworks, onToggle }) {return (ul{artworks.map(artwork (li key{artwork.id}labelinputtypecheckboxchecked{artwork.seen}onChange{e {onToggle(artwork.id,e.target.checked);}}/{artwork.title}/label/li))}/ul); }请注意当使用 Immer 时类似 artwork.seen nextSeen 这种会产生 mutation 的语法不会再有任何问题了 updateMyTodos(draft {const artwork draft.find(a a.id artworkId);artwork.seen nextSeen; });这是因为并不是在直接修改原始的 state而是在修改 Immer 提供的一个特殊的 draft 对象。同理也可以为 draft 的内容使用 push() 和 pop() 这些会直接修改原值的方法。 在幕后Immer 总是会根据对 draft 的修改来从头开始构建下一个 state。这使得你的事件处理程序非常的简洁同时也不会直接修改 state。 摘要 可以把数组放入 state 中但不应该直接修改它。不要直接修改数组而是创建它的一份 新的 拷贝然后使用新的数组来更新它的状态。可以使用 [...arr, newItem] 这样的数组展开语法来向数组中添加元素。可以使用 filter() 和 map() 来创建一个经过过滤或者变换的数组。可以使用 Immer 来保持代码简洁。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/914211.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

兰州新区建设银行网站简述软件开发流程

本文内容 先决条件创建新的控制台应用程序添加接口添加默认实现添加需要 DI 的服务为 DI 注册服务结束语 本文介绍如何在 .NET 中使用依赖注入 (DI)。 借助 Microsoft 扩展,可通过添加服务并在 IServiceCollection 中配置这些服务来管理 DI。 IHost 接口会公开 IS…

深圳网站建设lxhd家政服务网站做推广有效果吗

KB2919442 下载地址:https://www.microsoft.com/zh-cn/download/confirmation.aspx?id42153 KB2919355 下载地址:https://www.microsoft.com/zh-cn/download/confirmation.aspx?id42153 安装步骤:先安装442,后安装355

盘锦做网站的公司wordpress网站地图提交

参考资料:生物统计学 https://real-statistics.com/one-way-analysis-of-variance-anova/unplanned-comparisons/tukey-hsd/ Tukey法是基于学生化极差分布计算最小显著极差(LSR),根据平均数个数调整最小显著极差。 LSR&#xff1…

如何做微信小程序步骤深圳网站优化团队

1.忍受大法 第一种解决办法,很简单,无他,不管他,没有读到也没事。这时业务不需要任何改造,你好,我好,她也好~ 如果业务对于数据一致性要求不高,我们就可以采用这种方案。 2.数据同…

加强网站队伍建设建站平台软件

时间数据类型 1.mongo中存储时间大多为ISOData 2.获取当前时间   1. 使用new Date() 自动生成当前时间   2. 使用 ISODate() 生成当前时间   3. 获取计算机时间生成时间格式字符串 Date() 3.ISODate()   功能: 生成mongodb时间存储类型   参数&#xff1a…

做网站个网站要多少钱中国企业网站开发

爬虫专栏:http://t.csdnimg.cn/WfCSx 前言 在前一章中,我们了解了 Ajax 的分析和抓取方式,这其实也是 JavaScript 动态渲染的页面的一种情形,通过直接分析 Ajax,我们仍然可以借助 requests 或 urllib 来实现数据爬取…

广东品牌网站设计专家鹿寨建设局网站

本次实验将采用docker部署zabbix 5.2平台监控ESXI 6.5虚拟化系统—————————————————————————— 请自行准备环境: 关于docker部署方案请参考: docker之核心概念与安装 关于docker部署zabbix方案请参考: docker容器方式部署zabbix监控平台 关于ESXI安…

网站建设完成后期维护网站的seo

前言:本文会介绍 Android 与 iOS 两个平台的处理方式 一、Android高版本在应用退到后台时,系统为了省电会限制应用的后台活动,因此我们需要开启一个前台服务,在前台服务中发送常驻任务栏通知,以此来保证App 退到后台时不会被限制活动. 前台服务代码如下: package com.notify…

长春市长春网站建设高端型网站制作

什么是 resolvectl “resolvectl” 是一个用于管理系统 DNS 解析配置的命令行工具。它是 systemd-resolved 服务的一部分,该服务是在许多基于 Systemd 的 Linux 发行版中用于管理网络配置和 DNS 解析的系统服务。 通过 resolvectl 命令,可以查看当前系…

建设银行官方网站首页入口购物网站排名大全

题目:输入一个整数数组,判断该数组是不是某二元查找树的后序遍历的结果。 如果是返回true,否则返回false。 例如输入5、7、6、9、11、10、8,由于这一整数序列是如下树的后序遍历结果: 8 / \ 6 10 / \ / \ 5 7 9…

平台类网站有哪些广州市网站开发

-- 日、时、分、秒,这是计时的单位,惜时就应该惜日、惜时、惜分、惜秒。 用 Java 来读取 Excel 文件,检查每一行中的 URL,并将不符合条件的行标记为红色。以下是一个简单的示例,使用 Apache POI 进行 Excel 操作&#…

02020405 EF Core基础05-EF Core反向工程、EF Core和ADO.NET Core的联系、EF Core无法做到的事情

02020405 EF Core基础05-EF Core反向工程、EF Core和ADO.NET Core的联系、EF Core无法做到的事情 1. 数据库设计的三种形式(视频3-9)DB First → 先在数据库中将数据表建好了,然后再反向生成实体类。简单,但是不适…

02020406 EF Core基础06-EF Core生成的SQL

02020406 EF Core基础06-EF Core生成的SQL 1. 通过代码查看EF Core的SQL语句(视频3-12) 1.1 方法1:标准日志 // 标准日志用法示例 public static readonly ILoggerFactory MyLoggerFactory= LoggerFactory.Create(b…

北京网站建设工作南京专业做网站的公司有哪些

面试中的收获: 优点: 1. 设计用例考虑较为全面。 2. 自动化,性能都有涉猎,但不深入。 3. 对业务理解较深入。 缺点: 1. 接口自动化停留在初级阶段。 2. UI自动化了解较少。 3. 性能压测缺少数据清洗等步骤。 4. 算法还…

菲斯曼售后服务中心贵港seo关键词整站优化

拦截器-interceptor 在现代的一些前端框架上,拦截器基本上是很基础但很重要的一环,比如Angular原生就支持拦截器配置,VUE的Axios模块也给我们提供了拦截器配置,那么拦截器到底是什么,它有什么用?拦截器能帮…

网站打不开服务器错误建手机网站多少钱

给定一个数组 candidates 和一个目标数 target ,找出 candidates 中所有可以使数字和为 target 的组合。 candidates 中的每个数字在每个组合中只能使用一次。 说明: 所有数字(包括目标数)都是正整数。解集不能包含重复的组合。 …

温州专业网站建设公司wordpress的链接怎么设置

把这个项目的文档迁入到SVN Server上的库中 【1】首先右键点击projectAdmin目录,这时候的右键菜单例如以下图看到的:选择copy URL toCLipboard,就是复制统一资源定位符(URL)到剪贴板中 https://KJ-AP01.中国.corpnet:8443/svn/pro…

中山建设监理有限公司 网站扁平化网站首页

随着数字化时代的来临,装修小程序成为提升服务质量和效率的关键工具。装修小程序旨在为装修公司提供数字化赋能、提高客户满意度的智慧装修平台。通过装修小程序,装修公司能够与客户进行在线沟通、展示设计方案、提高服务满意度等操作。 装修小程序的好处…

服装商城网站模板wordpress极简模板

前言 整理这个官方翻译的系列,原因是网上大部分的 tomcat 版本比较旧,此版本为 v11 最新的版本。 开源项目 从零手写实现 tomcat minicat 别称【嗅虎】心有猛虎,轻嗅蔷薇。 系列文章 web server apache tomcat11-01-官方文档入门介绍 web…