我正在使用 ... spread 语法替换反应状态数组中的项目。这有效:
let newImages = [...this.state.images]
newImages[4] = updatedImage
this.setState({images:newImages})
是否有可能在一行代码中做到这一点?像这样的东西?(这显然不起作用......)
this.setState({images: [...this.state.images, [4]:updatedImage})
我正在使用 ... spread 语法替换反应状态数组中的项目。这有效:
let newImages = [...this.state.images]
newImages[4] = updatedImage
this.setState({images:newImages})
是否有可能在一行代码中做到这一点?像这样的东西?(这显然不起作用......)
this.setState({images: [...this.state.images, [4]:updatedImage})
this.setState({images: [...this.state.images.slice(0, 4), updatedImage, ...this.state.images.slice(5)]})
从原始帖子编辑:更改 slice 方法的第二个参数中的 3 oa 4 ,因为第二个参数指向超出最后一个保留的数组成员,它现在正确回答了原始问题。
Object.assign
做这项工作:
this.setState({images: Object.assign([], this.state.images, {4: updatedImage}));
...但涉及一个临时对象(最后的那个)。尽管如此,只有一个临时对象......如果你这样做slice
并分散数组,它会涉及更多的临时对象(来自的两个数组slice
,它们的迭代器,通过调用迭代器的next
函数创建的结果对象[在...
句柄内], ETC。)。
它之所以有效,是因为普通的 JS 数组并不是真正的数组1 (这当然需要优化),它们是具有一些特殊功能的对象。它们的“索引”实际上是符合某些标准的属性名称2。所以在那里,我们展开this.state.images
到一个新数组中,将它Object.assign
作为目标传递给一个对象,并给出Object.assign
一个具有名为的属性的对象"4"
(是的,它最终是一个字符串,但我们可以将它写为一个数字)我们要更新的值。
现场示例:
const a = [0, 1, 2, 3, 4, 5, 6, 7];
const b = Object.assign([], a, {4: "four"});
console.log(b);
如果4
可以是变量,那很好,您可以使用计算属性名称(ES2015 中的新功能):
let n = 4;
this.setState({images: Object.assign([], this.state.images, {[n]: updatedImage}));
注意[]
周围n
。
现场示例:
const a = [0, 1, 2, 3, 4, 5, 6, 7];
const index = 4;
const b = Object.assign([], a, {[index]: "four"});
console.log(b);
1披露:这是我贫血的小博客上的一篇文章。
2这是项目符号列表之后的第二段:
整数索引是字符串值的属性键,它是规范的数字字符串(参见 7.1.16),其数值为+0或正整数 ≤ 2 53 -1。数组索引是一个整数索引,其数值i在 +0 ≤ i < 2 32 -1 范围内。
所以这Object.assign
和你的 create-the-array-then-update-index-4 一样。
您可以使用地图:
const newImages = this.state.images
.map((image, index) => index === 4 ? updatedImage : image)
您可以将数组转换为对象(...array1
),替换项目([1]:"seven"
),然后将其转换回数组(Object.values
):
array1 = ["one", "two", "three"];
array2 = Object.values({...array1, [1]:"seven"});
console.log(array1);
console.log(array2);
这是我的自我解释非单行
const wantedIndex = 4;
const oldArray = state.posts; // example
const updated = {
...oldArray[wantedIndex],
read: !oldArray[wantedIndex].read // attributes to change...
}
const before = oldArray.slice(0, wantedIndex);
const after = oldArray.slice(wantedIndex + 1);
const menu = [
...before,
updated,
...after
]
我参考了@Bardia Rastin 解决方案,我发现该解决方案在索引值处有错误(它替换了索引 3 但不是 4 处的项目)。
如果要替换具有索引值的项目,索引,答案应该是
this.setState({images: [...this.state.images.slice(0, index), updatedImage, ...this.state.images.slice(index + 1)]})
this.state.images.slice(0, index)
是一个新数组,其项目从 0 开始到索引 - 1(不包括索引)
this.state.images.slice(index)
是一个新数组,其项目从index 开始,然后。
要正确替换索引 4 处的项目,答案应该是:
this.setState({images: [...this.state.images.slice(0, 4), updatedImage, ...this.state.images.slice(5)]})
先找到索引,这里我用图片文档id docId作为说明:
const index = images.findIndex((prevPhoto)=>prevPhoto.docId === docId)
this.setState({images: [...this.state.images.slice(0,index), updatedImage, ...this.state.images.slice(index+1)]})
我已经尝试了很多使用扩展运算符。我认为当您使用 splice() 时,它会更改主数组。所以我发现的解决方案是在新变量中克隆数组,然后使用扩展运算符将其拆分。我用的例子。
var cart = [];
function addItem(item) {
let name = item.name;
let price = item.price;
let count = item.count;
let id = item.id;
cart.push({
id,
name,
price,
count,
});
return;
}
function removeItem(id) {
let itemExist = false;
let index = 0;
for (let j = 0; j < cart.length; j++) {
if (cart[j].id === id) { itemExist = true; break; }
index++;
}
if (itemExist) {
cart.splice(index, 1);
}
return;
}
function changeCount(id, newCount) {
let itemExist = false;
let index = 0;
for (let j = 0; j < cart.length; j++) {
console.log("J: ", j)
if (cart[j].id === id) {
itemExist = true;
index = j;
break;
}
}
console.log(index);
if (itemExist) {
let temp1 = [...cart];
let temp2 = [...cart];
let temp3 = [...cart];
cart = [...temp1.splice(0, index),
{
...temp2[index],
count: newCount
},
...temp3.splice(index + 1, cart.length)
];
}
return;
}
addItem({
id: 1,
name: "item 1",
price: 10,
count: 1
});
addItem({
id: 2,
name: "item 2",
price: 11,
count: 1
});
addItem({
id: 3,
name: "item 3",
price: 12,
count: 2
});
addItem({
id: 4,
name: "item 4",
price: 13,
count: 2
});
changeCount(4, 5);
console.log("AFTER CHANGE!");
console.log(cart);