我正在使用扩展语法来替换数组中的对象,但我无法将该对象添加为数组的新条目。
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)
然后我使用 spread 语法创建一个新状态并替换数组中的元素:
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
}
]}
您可以使用Object.assign
来更新找到的对象的属性(使用Array#find
(。
let object = state[payload.id].find((element)=> element.id === payload.data.id);
Object.assign(object, payload.data);
扩展语法/运算符用于将对象扩展为逗号分隔的键。
在您的状态下,每个键都是有效负载 id,您希望替换该有效负载值中的一个条目,即数组。因此,您需要按 id 转到该有效负载,转到该有效负载值数组中的索引并将该值替换为新值。下面的代码应该给你预期的输出,
let index = state[payload.id].findIndex((element)=> element.id === payload.data.id);
state[payload.id][index] = payload.data;
console.log(state);
当您想要替换该有效负载的完整数组时,您应该使用 spread 语法,而这里您想要替换该数组中的条目而不是完整数组。
编辑以避免突变
1. 使用 Object.assign 将改变状态,
let index = state[payload.id].findIndex((element)=> element.id === payload.data.id);
let stateCopy = Object.assign({}, state);
stateCopy[payload.id][index] = payload.data;
console.log(state);
console.log(stateCopy);
检查状态和状态副本是否被修改
2.使用扩展语法会改变状态,
let index = state[payload.id].findIndex((element)=> element.id === payload.data.id);
let stateCopy = {...state}
stateCopy[payload.id][index] = payload.data;
console.log(state);
console.log(stateCopy);
检查状态和状态副本是否被修改
3.使用克隆避免原始状态的突变,
安装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 库。