简体   繁体   English

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

[英]How to delete an item from state array?

The story is, I should be able to put Bob, Sally and Jack into a box.故事是,我应该能够将 Bob、Sally 和 Jack 放入一个盒子中。 I can also remove either from the box.我也可以从盒子里取出任何一个。 When removed, no slot is left.移除后,不会留下任何插槽。

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

I now need to remove, say, "Bob".我现在需要删除,比如说,“鲍勃”。 The new array would be:新数组将是:

["Sally", "Jack"]

Here is my react component:这是我的反应组件:

...

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];
},

...

Here I show you a minimal code as there is more to it (onClick etc).在这里,我向您展示了一个最少的代码,因为它还有更多内容(onClick 等)。 The key part is to delete, remove, destroy "Bob" from the array but removePeople() is not working when called.关键部分是从数组中删除、移除、销毁“Bob”,但removePeople()在调用时不起作用。 Any ideas?有任何想法吗? I was looking at this but I might be doing something wrong since I'm using React.我正在看这个,但由于我使用的是 React,所以我可能做错了什么。

When using React, you should never mutate the state directly.使用 React 时,你永远不应该直接改变状态。 If an object (or Array , which is an object too) is changed, you should create a new copy.如果一个对象(或Array也是一个对象)被更改,您应该创建一个新副本。

Others have suggested using Array.prototype.splice() , but that method mutates the Array, so it's better not to use splice() with React.其他人建议使用Array.prototype.splice() ,但该方法会改变 Array,因此最好不要将splice()与 React 一起使用。

Easiest to use Array.prototype.filter() to create a new array:最容易使用Array.prototype.filter()创建一个新数组:

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

To remove an element from an array, just do:要从数组中删除元素,只需执行以下操作:

array.splice(index, 1);

In your case:在你的情况下:

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});
  }
},

Here is a minor variation on Aleksandr Petrov's response using ES6这是 Aleksandr Petrov 使用 ES6 的响应的一个小变化

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

Use .splice to remove item from array.使用.splice从数组中删除项目。 Using delete , indexes of the array will not be altered but the value of specific index will be undefined使用delete ,数组的索引不会改变,但特定索引的值将是undefined

The splice() method changes the content of an array by removing existing elements and/or adding new elements. splice()方法通过删除现有元素和/或添加新元素来更改数组的内容。

Syntax: array.splice(start, deleteCount[, item1[, item2[, ...]]])语法: 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);

Edit:编辑:

As pointed out byjustin-grant , As a rule of thumb, Never mutate this.state directly, as calling setState() afterward may replace the mutation you made.正如justin-grant所指出的,根据经验,永远不要直接改变this.state ,因为之后调用setState()可能会替换你所做的改变。 Treat this.state as if it were immutable.this.state视为不可变的。

The alternative is, create copies of the objects in this.state and manipulate the copies, assigning them back using setState() .另一种方法是,在this.state中创建对象的副本并操作副本,使用setState()将它们分配回去。 Array#map , Array#filter etc. could be used.可以使用Array#mapArray#filter等。

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

Simple solution using slice without mutating the state使用slice而不改变状态的简单解决方案

const [items, setItems] = useState(data);
const removeItem = (index) => {
  setItems([
             ...items.slice(0, index),
             ...items.slice(index + 1)
           ]);
}

Easy Way To Delete Item From state array in react:从反应状态数组中删除项目的简单方法:

when any data delete from database and update list without API calling that time you pass deleted id to this function and this function remove deleted recored from list当任何数据从数据库中删除并更新列表而不调用 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) }) } }

filter method is the best way to modify the array without touching the state. filter方法是在不触及状态的情况下修改数组的最佳方法。

It returns a new array based on the condition.它根据条件返回一个新数组。

In your case filter check the condition person.id !== id and create a new array excluding the item based on condition.在您的情况下,过滤器检查条件person.id !== id并根据条件创建一个不包括项目的新数组。

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

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

   setPeople( newPeople);
 };

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

Not advisable: But you can also use an item index for the condition if you don't have any id.不建议:但如果您没有任何 id,您也可以使用项目索引作为条件。

index !== itemIndex

Some answers mentioned using 'splice', which did as Chance Smith said mutated the array.使用'splice'提到的一些答案正如Chance Smith所说的那样改变了数组。 I would suggest you to use the Method call 'slice' (Document for 'slice' is here) which make a copy of the original array.我建议您使用方法调用'slice' ('slice' 的文档在这里)复制原始数组。

This is your current state variable:这是您当前的状态变量:

const [animals, setAnimals] = useState(["dogs", "cats", ...])

Call this function and pass the item you would like to remove.调用此函数并传递您要删除的项目。

removeItem("dogs")

const removeItem = (item) => {
    setAnimals((prevState) =>
      prevState.filter((prevItem) => prevItem !== item)
    );
  };

your state variable now becomes:您的状态变量现在变为:

["cats", ...]

Another way of doing it is by using useState hook.另一种方法是使用useState钩子。 Check docs: https://reactjs.org/docs/hooks-reference.html#functional-updates It states: Unlike the setState method found in class components, useState does not automatically merge update objects.查看文档: https ://reactjs.org/docs/hooks-reference.html#functional-updates 它指出:与类组件中的 setState 方法不同,useState 不会自动合并更新对象。 You can replicate this behavior by combining the function updater form with object spread syntax as shown below or use useReducer hook.您可以通过将函数更新程序表单与对象扩展语法相结合来复制此行为,如下所示或使用useReducer挂钩。

const [state, setState] = useState({});
setState(prevState => {
  return {...prevState, ...updatedValues};
});
const [people, setPeople] = useState(data);

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

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

Just filter out deleted item and update the state with remaining items again,只需过滤掉已删除的项目并再次使用剩余项目更新状态,

let remainingItems = allItems.filter((item) => {return item.id !== item_id});
    
setItems(remainingItems);
removePeople(e){
    var array = this.state.people;
    var index = array.indexOf(e.target.value); // Let's say it's Bob.
    array.splice(index,1);
}

Redfer doc for more info Redfer 文档以获取更多信息

It's Very Simple First You Define a value首先定义一个值非常简单

state = {
  checked_Array: []
}

Now,现在,

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

Almost all the answers here seem to be for class components, here's a code that worked for me in a functional component.这里几乎所有的答案似乎都是针对类组件的,这是一个在功能组件中对我有用的代码。

const [arr,setArr]=useState([]);
const removeElement=(id)=>{
    var index = arr.indexOf(id)
    if(index!==-1){
      setArr(oldArray=>oldArray.splice(index, 1));
    }
}

If you use:如果您使用:

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

for add:添加:

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

and for remove:并删除:

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

Removing an element with a certain value // Note filter function always returns a new array.删除具有特定值的元素//注意过滤器 function 总是返回一个新数组。

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

You forgot to use setState .你忘了使用setState Example:例子:

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

But it's better to use filter because it does not mutate array.但最好使用filter ,因为它不会改变数组。 Example:例子:

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

I also had a same requirement to delete an element from array which is in state.我也有相同的要求从处于状态的数组中删除一个元素。

const array= [...this.state.selectedOption]
const found= array.findIndex(x=>x.index===k)
if(found !== -1){
   this.setState({
   selectedOption:array.filter(x => x.index !== k)
    })
 }

First I copied the elements into an array.首先,我将元素复制到数组中。 Then checked whether the element exist in the array or not.然后检查该元素是否存在于数组中。 Then only I have deleted the element from the state using the filter option.然后只有我使用过滤器选项从状态中删除了元素。

const array = [...this.state.people];
array.splice(i, 1);
this.setState({people: array});         
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);

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM