在一行代码中用扩展语法替换数组条目?

IT技术 javascript reactjs spread-syntax
2021-04-30 03:35:36

我正在使用 ... spread 语法替换react状态数组中的项目。这有效:

let newImages = [...this.state.images]
newImages[4] = updatedImage
this.setState({images:newImages})

是否可以在一行代码中做到这一点?像这样的东西?(这显然不起作用......)

this.setState({images: [...this.state.images, [4]:updatedImage})
4个回答

使用Array.slice

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函数创建的结果对象[在...句柄内部], 等等。)。

它之所以有效,是因为普通的 JS 数组并不是真正的数组1 (当然,这需要优化),它们是具有一些特殊功能的对象。它们的“索引”实际上是满足特定标准2 的属性名称因此,我们将展开this.state.images到一个新数组中,将其Object.assign作为目标传递Object.assign对象,并提供一个具有命名属性的对象"4"(是的,它最终是一个字符串,但我们可以将其写为数字)我们要更新的值。

现场示例:

如果4可以是变量,那很好,您可以使用计算属性名称(ES2015 中的新功能):

let n = 4;
this.setState({images: Object.assign([], this.state.images, {[n]: updatedImage}));

注意[]周围n

现场示例:


1披露:这是我贫血的小博客上的一篇文章。

2这是项目符号列表之后的第二段:

一个整数指数是一个字符串值属性密钥是一个规范的数字串(见7.1.16),并且其数字值是0或正整数2≤ 53 -1。一个数组索引是一个整数指数,其数值的范围是从0≤<2 32 -1。

所以这Object.assign和你的 create-the-array-then-update-index-4 做同样的事情。

您可以使用地图:

const newImages = this.state.images
  .map((image, index) => index === 4 ? updatedImage : image)

您可以将数组转换为对象 (the ...array1),替换项目 (the [1]:"seven"),然后将其转换回数组 ( Object.values) :

array1 = ["one", "two", "three"];
array2 = Object.values({...array1, [1]:"seven"});
console.log(array1);
console.log(array2);