从组件状态的数组中删除元素

Removing element from array in component state

本文关键字:删除 元素 数组 组件 状态      更新时间:2023-09-26

我正在尝试找到从组件状态的数组中删除元素的最佳方法。 由于我不应该直接修改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 中使用回调。在更新当前状态时引用当前状态时,应执行此操作。

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

removeItem(index) {
  this.setState({
    data: this.state.data.filter((_, i) => i !== index)
  });
}
您可以使用

react-addons-update 中的 update() 不可变性助手,它有效地在引擎盖下做同样的事情,但你正在做的很好。

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

我认为不鼓励在setState()内部引用this.state(状态更新可能是异步的(。

文档建议将 setState() 与回调函数一起使用,以便在更新发生时在运行时传入 prevState。所以这就是它的外观:

使用不带 ES6 的 Array.prototype.filter

removeItem : function(index) {
  this.setState(function(prevState){
    return { data : prevState.data.filter(function(val, i) {
      return i !== index;
    })};
  });
}

将 Array.prototype.filter 与 ES6 箭头函数结合使用

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

使用不可变性帮助程序

import update from 'immutability-helper'
...
removeItem(index) {
  this.setState((prevState) => ({
    data: update(prevState.data, {$splice: [[index, 1]]})
  }))
}

使用点差

function removeItem(index) {
  this.setState((prevState) => ({
    data: [...prevState.data.slice(0,index), ...prevState.data.slice(index+1)]
  }))
}

请注意,在每个实例中,无论使用何种技术,this.setState()都会传递一个回调,而不是对旧this.state的对象引用;

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

onRemovePerson: (index) => {
  const data = this.state.data;
  this.setState({ 
    data: [...data.slice(0,index), ...data.slice(index+1)]
  });
}
我想

在这里插话,即使这个问题已经被@pscl正确回答,以防其他人遇到我所做的相同问题。 在给出的 4 种方法中,我选择将 es6 语法与箭头函数一起使用,因为它简洁且不依赖于外部库:

将 Array.prototype.filter 与 ES6 箭头函数结合使用

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

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

如果您在客户端删除元素时看到奇怪的行为,另一个有用的点是永远不要使用数组的索引作为元素的键

// 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>
)}

以上是相关帖子中这个答案的摘录。

祝大家编码愉快!

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

作为替代方案,可以简单地"切片"出所需的元素并连接片段。

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

希望这有帮助!

如果你想删除元素(没有索引(,你可以使用这个函数

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

您可以使用一行帮助程序函数使代码更具可读性:

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

然后像这样使用它:

this.setState(state => ({ places: removeElement(state.places, index) }));

只是一个建议,在您的代码中,您可以使用 ES6 中引入的 spread 而不是使用let newData = prevState.data您可以使用 let newData = ...prevState.data 来复制数组

三个点...表示点差运算符或休息参数,

它允许数组表达式或字符串或任何可以迭代的内容在需要零个或多个函数调用参数或数组元素的地方扩展。

此外,您可以通过以下方式从数组中删除项目

onRemovePerson: function(index) {
  this.setState((prevState) => ({
    data: [...prevState.data.slice(0,index), ...prevState.data.slice(index+1)]
  }))
}

希望这有所贡献!!

In react setState

const [array, setArray] = useState<any>([]);
//element you want to remove
let temp = array.filter((val: number) => {
    return val !== element;
 });
setArray(temp);

这是一个简单的方法:

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.
}

希望对您有所帮助!!