在组件状态下从数组中删除元素

我试图找到一种在组件状态下从数组中删除元素的最佳方法。由于我不应该this.state直接修改变量,是否有比我在这里有更好的方法(更简洁)从数组中删除元素?:

  onRemovePerson: function(index) {
    this.setState(prevState => { // pass callback in setState to avoid race condition
      let newData = prevState.data.slice() //copy array from prevState
      newData.splice(index, 1) // remove element
      return {data: newData} // update state
    })
  },

谢谢。

更新

这已更新为在setState中使用回调。在更新时引用当前状态时,应执行此操作。

卡卡西阿飞2020/03/11 17:54:04

我正在使用它,希望它没有问题和帮助。

removeItem(item){
    const index = this.state.yourArray.indexOf(item);
    if (index < 0) return
    let yourArray = [...this.state.yourArray]
    yourArray.splice(index, 1)
    this.setState({yourArray: this.state.yourArray})
}
Mandy路易2020/03/11 17:54:04

这是一种简单的方法:

removeFunction(key){
  const data = {...this.state.data}; //Duplicate state.
  delete data[key];                  //remove Item form stateCopy.
  this.setState({data});             //Set state as the modify one.
}

希望能帮助到你!!!

猿阿飞Tom2020/03/11 17:54:04

您可以使用单行辅助函数使代码更具可读性:

const removeElement = (arr, i) => [...arr.slice(0, i), ...arr.slice(i+1)];

然后像这样使用它:

this.setState(state => ({ places: removeElement(state.places, index) }));
逆天米亚2020/03/11 17:54:04

正如上面对ephrion的答案的评论中提到的,filter()可能很慢,尤其是对于大型数组,因为它会循环查找似乎已经确定的索引。这是一个干净但效率低下的解决方案。

另一种选择是,可以简单地“切出”所需的元素并连接片段。

var dummyArray = [];    
this.setState({data: dummyArray.concat(this.state.data.slice(0, index), this.state.data.slice(index))})

希望这可以帮助!

乐伽罗古一2020/03/11 17:54:04

这是一种使用ES6扩展语法从状态中删除数组中元素的方法。

onRemovePerson: (index) => {
  const data = this.state.data;
  this.setState({ 
    data: [...data.slice(0,index), ...data.slice(index+1)]
  });
}
达蒙阿飞斯丁2020/03/11 17:54:04

如果要删除元素(不带索引),则可以使用此功能

removeItem(item) {
  this.setState(prevState => {
    data: prevState.data.filter(i => i !== item)
  });
}
猿小小2020/03/11 17:54:04

即使其他人遇到与我相同的问题,@ pscl已经正确回答了这个问题,但我还是想在这里提出建议在这4种方法中,我选择使用es6语法和箭头函数,因为它简洁明了且不依赖外部库:

将Array.prototype.filter与ES6箭头函数一起使用

removeItem(index) {
  this.setState((prevState) => ({
    data: prevState.data.filter((_, i) => i != index)
  }));
}

如您所见,我做了一些小的修改以忽略索引(!==to !=的类型,因为在我的情况下,我是从字符串字段中检索索引的。

如果在客户端删除元素时看到奇怪的行为,则另一个有用的观点是,切勿使用数组的索引作为元素的键

// bad
{content.map((content, index) =>
  <p key={index}>{content.Content}</p>
)}

当React对虚拟DOM进行更改时,它将查看键以确定已更改的内容。因此,如果您使用的是索引,但数组中少了一个,它将删除最后一个。而是将内容的ID用作键,像这样。

// good
{content.map(content =>
  <p key={content.id}>{content.Content}</p>
)}

上面是相关帖子的答案摘录

大家快乐编码!

樱小小小小2020/03/11 17:54:04

我见过的最干净的方法是filter

removeItem(index) {
  this.setState({
    data: this.state.data.filter((_, i) => i !== index)
  });
}
古一Mandy2020/03/11 17:54:04

您可以使用update()来自react-addons-update不变性帮助程序,该帮助程序实际上可以在后台执行相同的操作,但是您正在做的事情很好。

this.setState(prevState => ({
  data: update(prevState.data, {$splice: [[index, 1]]})
}))