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

275

这个故事是,我应该能够把Bob、Sally和Jack放进一个盒子里。我也可以从盒子中移除其中任何一个。当被移除时,不会留下空位。

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

现在我需要删除“Bob”。新的数组将是:

["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,所以可能做错了什么。


问题在于您正在改变您的集合。该集合仍然指向相同的数组引用,因此它不会被视为已更改(变量仍然指向相同的数组),因此它不会重新渲染。一种常见的实现方法是复制原始状态,对其进行修改,然后使用副本覆盖当前状态,这将是一个新的数组引用,并被视为已更改,从而导致渲染更新。 - CTS_AE
18个回答

2
const [people, setPeople] = useState(data);

const handleRemove = (id) => {
   const newPeople = people.filter((person) => { person.id !== id;
     setPeople( newPeople );
     
   });
 };

<button onClick={() => handleRemove(id)}>Remove</button>

2
你的代码还未完成,请检查和修正它。还需要确保不仅提供代码,而且也要解释代码。 - Vimal Patel

1

如果你使用:

const[myArr, setMyArr] = useState([]);

对于添加:

setMyArr([...myArr, value]);

而对于删除:

let index = myArr.indexOf(value);
if(index !== -1)
    setPatch([...myArr.slice(0, index), ...myArr.slice(index, myArr.length-1)]);

我想出了这个一句话: setMyArr(myArr.slice(0, myArr.length - 1)); - sFritsch09

0

这很简单,首先你需要定义一个值

state = {
  checked_Array: []
}

现在,

fun(index) {
  var checked = this.state.checked_Array;
  var values = checked.indexOf(index)
  checked.splice(values, 1);
  this.setState({checked_Array: checked});
  console.log(this.state.checked_Array)
}

1
请不要这样做。它会直接改变状态。splice是原地操作。 - ggorlen

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

请查看doc以获取更多信息


1
这会直接改变状态。不要这样做 - 总是将状态视为不可变的。 - ggorlen

0

删除具有特定值的元素 // 请注意,过滤函数始终返回一个新数组。

const people = ["Bob", "Sally", "Jack"]
    
const removeEntry = (remove) => {
const upDatePeople = people.filter((Person) =>{
return Person !== remove
});
console.log(upDatePeople)
//Output: [ 'Sally', 'Jack' ]
}
removeEntry("Bob");

1
欢迎来到SO!请不要只贴代码作为答案,而是添加一些文字说明你的方法如何工作,为什么它有效,以及与其他给出的答案有什么不同之处。您可以在我们的“如何撰写好的答案”页面找到更多信息。 - ahuemmer

0
几乎所有的答案都是针对类组件的,这里是一个在函数式组件中适用的代码,它对我很有效。
const [arr,setArr]=useState([]);
const removeElement=(id)=>{
    var index = arr.indexOf(id)
    if(index!==-1){
      setArr(oldArray=>oldArray.splice(index, 1));
    }
}

splice 不会返回新数组,它是原地操作的。 - ggorlen

-1
你忘记使用 setState 了。示例:
removePeople(e){
  var array = this.state.people;
  var index = array.indexOf(e.target.value); // Let's say it's Bob.
  delete array[index];
  this.setState({
    people: array
  })
},

但最好使用filter,因为它不会改变数组。 例如:

removePeople(e){
  var array = this.state.people.filter(function(item) {
    return item !== e.target.value
  });
  this.setState({
    people: array
  })
},

但最好使用filter,因为它不会改变数组 - 为什么要展示顶部版本呢?因为它很容易让人感到困惑、不正确和有缺陷。我理解你试图使用OP的例子,但即使使用setState,在状态上使用delete也是基本有问题的。 - ggorlen

-3
const [randomNumbers, setRandomNumbers] = useState([111,432,321]);
const numberToBeDeleted = 432;

// Filter (preferred)
let newRandomNumbers = randomNumbers.filter(number => number !== numberToBeDeleted)
setRandomNumbers(newRandomNumbers);

//Splice (alternative)
let indexOfNumberToBeDeleted = randomNumbers.indexOf(numberToBeDeleted);
let newRandomNumbers = Array.from(randomNumbers);
newRandomNumbers.splice(indexOfNumberToBeDeleted, 1);
setRandomNumbers(newRandomNumbers);


//Slice (not preferred - code complexity)
let indexOfNumberToBeDeleted = randomNumbers.indexOf(numberToBeDeleted);
let deletedNumber = randomNumbers.slice(indexOfNumberToBeDeleted, indexOfNumberToBeDeleted+1);
let newRandomNumbers = [];
for(let number of randomNumbers) {
    if(deletedNumber[0] !== number)
        newRandomNumbers.push(number);
};
setRandomNumbers(newRandomNumbers);

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接