反应状态:更新数组对象的索引而不显式指定键

React state : update an index of array objects without explicitly specifying keys

我的状态下有一组对象。我想更新数组中的最后一个对象。但我不想在更新对象时明确提及键。

这就是我的代码现在的样子。

import React from 'react'
import update from 'immutability-helper'

class Container extends React.Component {
  state = { queue: [
    {title: 'title 1', message: 'message 1', dismissible: false},
    {title: 'title 2', message: 'message 2', dismissible: true},
    {title: 'title 3', message: 'message 3', dismissible: false},
  ] }
  updateLast = (contents) => {
    this.setState({
      queue: update(this.state.queue, {
        [this.state.queue.length-1]: {
          title: {$set: contents.title},
          message: {$set: contents.message},
          dismissible: {$set: contents.dismissible},
        },
      }),
    })
  }

  render() {
    return (
      <div className="notifications">
        {this.state.queue.map((notification, key) => (
          <Notification key={key} {...notification} />
        ))}
      </div>
    )
  }

如您所见,在 update 方法中,我明确指定了对象键 titlemessage 等。 有什么方法可以使用 mapspread ... 运算符更新对象的所有键?

使用扩展运算符,您可以切掉数组中的最后一项,然后创建一个新对象来取代它,如下所示:

updateLast = (contents) => {
  this.setState({
    queue: [...this.state.queue.slice(0, -1), {
      title: {$set: contents.title},
      message: {$set: contents.message},
      dismissible: {$set: contents.dismissible},
    }],
  })
}

如果 contents 对象与数组中的项目具有相同的形状,您可以直接添加对象。您可以使用 .slice(0, -1) 删除最后一个索引,然后使用 .concat 将新项目添加到末尾。还要确保使用 setState 的回调形式,并在新状态以某种方式依赖于前一个状态时始终这样做。

this.setState((state) => ({
  queue: state.queue.slice(0, -1).concat(contents),
}))

数组传播在这里也适用。

this.setState((state) => ({
  queue: [...state.queue.slice(0, -1), contents],
}))