如何从状态数组中删除一个项目?

IT技术 javascript arrays reactjs
2021-01-30 11:05:28

故事是,我应该能够把鲍勃、莎莉和杰克放进一个盒子里。我也可以从盒子中取出。移除后,没有留下任何插槽。

people = ["Bob", "Sally", "Jack"]

我现在需要删除,比如“鲍勃”。新数组将是:

["Sally", "Jack"]

这是我的react组件:

...

getInitialState: function() {
  return{
    people: [],
  }
},

selectPeople(e){
  this.setState({people: this.state.people.concat([e.target.value])})
},

removePeople(e){
  var array = this.state.people;
  var index = array.indexOf(e.target.value); // Let's say it's Bob.
  delete array[index];
},

...

在这里,我向您展示了一个最少的代码,因为它还有更多内容(onClick 等)。关键部分是从数组中删除、移除、销毁“Bob”,但removePeople()在调用时不起作用。有任何想法吗?我正在看这个,但由于我使用的是 React,所以我可能做错了什么。

6个回答

使用 React 时,永远不要直接改变状态。如果一个对象(或者Array,它也是一个对象)被改变了,你应该创建一个新的副本。

其他人建议使用Array.prototype.splice(),但该方法会改变 Array,因此最好不要splice()与 React一起使用

最容易用于Array.prototype.filter()创建新数组:

removePeople(e) {
    this.setState({people: this.state.people.filter(function(person) { 
        return person !== e.target.value 
    })});
}
有不可变的切片和可变的拼接
2021-03-11 11:05:28
或使用索引: this.state.people.filter((_, i) => i !== index)
2021-03-17 11:05:28
根据永不改变状态的 React 习惯用法,这应该是公认的答案。
2021-03-19 11:05:28
是的,这是声明性的方式。使用 prevState 和箭头函数的替代方法:this.setState(prevState => ({ people: prevState.people.filter(person => person !== e.target.value) }));
2021-03-23 11:05:28
这个答案的问题是,如果您有几个同名的人,您将删除所有这些人。在您可能有被骗的情况下,使用索引更安全
2021-03-31 11:05:28

要从数组中删除元素,只需执行以下操作:

array.splice(index, 1);

在你的情况下:

removePeople(e) {
  var array = [...this.state.people]; // make a separate copy of the array
  var index = array.indexOf(e.target.value)
  if (index !== -1) {
    array.splice(index, 1);
    this.setState({people: array});
  }
},
就我而言,它是:array.splice(array, 1);谢谢
2021-03-11 11:05:28
在这种情况下,我建议使用 Array.from(this.state.items) 而不是扩展运算符。这是因为 Array.from 专门用于此用途。
2021-03-11 11:05:28
小建议,在拼接数组之前添加对“index !== -1”的检查,以防止不需要的删除。
2021-03-21 11:05:28
这是反模式。splice 函数变异或改变相同
2021-03-22 11:05:28
使用 React 时,通常应该避免直接改变状态。您应该创建一个新数组并使用setState().
2021-04-03 11:05:28

这是 Aleksandr Petrov 使用 ES6 的响应的一个小变化

removePeople(e) {
    let filteredArray = this.state.people.filter(item => item !== e.target.value)
    this.setState({people: filteredArray});
}

在react中从状态数组中删除项目的简单方法:

当任何数据从数据库中删除并更新列表而没有调用 API 时,您将删除的 id 传递给此函数,此函数从列表中删除已删除的记录

export default class PostList extends Component {
  this.state = {
      postList: [
        {
          id: 1,
          name: 'All Items',
        }, {
          id: 2,
          name: 'In Stock Items',
        }
      ],
    }


    remove_post_on_list = (deletePostId) => {
        this.setState({
          postList: this.state.postList.filter(item => item.post_id != deletePostId)
        })
      }
  
}

您能解释一下这与这个三年前的问题的其他 8 个答案有何不同吗?来自评论
2021-03-25 11:05:28
利用 item.post_id !== deletePostId
2021-04-04 11:05:28
在上面的代码中,它将重新创建新的数据数组,但跳过“deletePostId”这个 id
2021-04-10 11:05:28

用于.splice从数组中删除项目。使用delete,数组的索引不会改变,但特定索引的值将是undefined

拼接()方法改变阵列的通过去除现有元件和/或添加新元素的内容。

句法: array.splice(start, deleteCount[, item1[, item2[, ...]]])

var people = ["Bob", "Sally", "Jack"]
var toRemove = 'Bob';
var index = people.indexOf(toRemove);
if (index > -1) { //Make sure item is present in the array, without if condition, -n indexes will be considered from the end of the array.
  people.splice(index, 1);
}
console.log(people);

编辑:

正如justin-grant所指出的那样,根据经验,永远不要this.state直接变异,因为setState()之后调用可能会替换您所做的变异。将其this.state视为不可变的。

另一种方法是,创建对象this.state的副本并操作副本,使用setState(). Array#mapArray#filter等等,也可以被使用。

this.setState({people: this.state.people.filter(item => item !== e.target.value);});
确保不要使用 splice 或任何直接更改状态变量的方法。相反,您需要制作数组的副本,从副本中删除项目,然后将副本传递到setState. 其他答案包含有关如何执行此操作的详细信息。
2021-03-30 11:05:28