Javascript 使用扩展语法ES6
我正在使用扩展语法替换数组中的对象,但无法将该对象添加为数组的新条目Javascript 使用扩展语法ES6,javascript,Javascript,我正在使用扩展语法替换数组中的对象,但无法将该对象添加为数组的新条目 state = {8xf0y6ziyjabvozdd253nd:[ { "id": "894tuq4ut84ut8v4t8wun89g", "parentId": "8xf0y6ziyjabvozdd253nd", "timestamp": 1503045227866, "body": "Hi there! I ams a COMMENTSsg.", "author": "thing
state = {8xf0y6ziyjabvozdd253nd:[
{
"id": "894tuq4ut84ut8v4t8wun89g",
"parentId": "8xf0y6ziyjabvozdd253nd",
"timestamp": 1503045227866,
"body": "Hi there! I ams a COMMENTSsg.",
"author": "thingtwo",
"voteScore": 143,
"deleted": false,
"parentDeleted": false
},
]}
首先,我找到要用此函数替换的元素的索引:
let index = state[payload.id].findIndex((element)=> element.id === payload.data.id)
然后我使用扩展语法创建一个新状态并替换数组中的元素:
return { ...state,
[payload.id]:[...state[payload.id],index=payload.data]
}
但它返回的是:
{8xf0y6ziyjabvozdd253nd:[
{
"id": "894tuq4ut84ut8v4t8wun89g",
"parentId": "8xf0y6ziyjabvozdd253nd",
"timestamp": 1503045227866,
"body": "Hi there! I am a COMMENTS.",
"author": "thingtwo",
"voteScore": 143,
"deleted": false,
"parentDeleted": false
},
{
"id": "894tuq4ut84ut8v4t8wun89g",
"parentId": "8xf0y6ziyjabvozdd253nd",
"timestamp": 1503045227866,
"body": "Hi there! I am a COMMENTS Replace",
"author": "thingtwo",
"voteScore": 143,
"deleted": false,
"parentDeleted": false
}
]}
预期产出:
{8xf0y6ziyjabvozdd253nd:[
{
"id": "894tuq4ut84ut8v4t8wun89g",
"parentId": "8xf0y6ziyjabvozdd253nd",
"timestamp": 1503045227866,
"body": "Hi there! I am a COMMENTS Replace",
"author": "thingtwo",
"voteScore": 143,
"deleted": false,
"parentDeleted": false
}
]}
您可以使用更新找到的对象的属性
扩展语法/运算符用于将对象扩展为逗号分隔的键 在您的状态中,每个键都是有效负载id,您希望替换该有效负载值中的一个条目,该值是一个数组。因此,您需要按id转到该有效负载,转到该有效负载值数组中的索引,并用新值替换该值。下面的代码应该为您提供预期的输出
let index = state[payload.id].findIndex((element)=> element.id === payload.data.id);
state[payload.id][index] = payload.data;
console.log(state);
当您想要替换该有效负载的完整数组时,应该使用扩展语法,这里您想要替换该数组中的一个条目而不是完整数组
编辑以避免变异
一,。使用Object.assign将改变状态
检查状态和状态副本是否已修改
二,。使用扩展语法将改变状态
检查状态和StateCopy是否已修改
三,。使用克隆来避免原始状态的突变
安装esclone
#> npm install --savedev esclone
转到您的文件并添加导入
import esclone from "esclone";
并使用下面的代码实现预期的输出而不发生突变
let index = state[payload.id].findIndex((element)=> element.id === payload.data.id);
let stateCopy = esclone(state);
stateCopy[payload.id][index] = payload.data;
console.log(state);
console.log(stateCopy);
检查原始状态是否未修改
注意:Object.assign&spread语法只执行引用复制而不执行深度复制,因此需要使用某些深度克隆机制,如esclone库。没有spread运算符。有扩展语法,或扩展符号。实际上,数组扩展语法和对象扩展语法都有,所以弄清楚你在说什么是有用的。你能添加预期的输出吗。什么是索引中的数据=数据。。。你想把数据的值分配给索引吗?@torazaburo我猜这取决于,不知何故,MDN URL以Thank结尾,比如说,这是spread语法而不是spread运算符,我编辑了这个问题,并包含了预期的输出。事实上,我正在处理一些类似的示例,您可以看到该示例包括数组排列用法中的快速修复:但您正在修改状态,因为我使用排列语法,我不希望在end spread运算符中修改状态,也不希望在object.assign中进行浅层复制。我将检查是否可以根据您的需要改进我的答案。您可能需要使用克隆来避免变异。抱歉,如果您这样做,我不同意:let state={id:1,name:james}let newState={…state}newState.id=2 console.logstate.id/->1 console.logNewstate.id->2这意味着状态永远不会使用Spread进行变异。您的意思是,您不同意Spread操作符进行浅层复制吗?是的,它返回一个新对象。
#> npm install --savedev esclone
import esclone from "esclone";
let index = state[payload.id].findIndex((element)=> element.id === payload.data.id);
let stateCopy = esclone(state);
stateCopy[payload.id][index] = payload.data;
console.log(state);
console.log(stateCopy);