在反应中从状态数组中删除项目

Syl*_*lar 93 javascript arrays reactjs

故事是,我应该能把Bob,Sally和Jack放进盒子里.我也可以从包装盒中取出.删除后,不会留下任何插槽.

people = ["Bob", "Sally", "Jack"]
Run Code Online (Sandbox Code Playgroud)

我现在需要删除,比如"Bob".新阵列将是:

["Sally", "Jack"]
Run Code Online (Sandbox Code Playgroud)

这是我的反应组件:

...

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

...
Run Code Online (Sandbox Code Playgroud)

在这里,我向您展示了一个最小的代码,因为它有更多(onClick等).关键部分是从数组中删除,删除,销毁"Bob",但removePeople()在调用时不起作用.有任何想法吗?我正在看这个,但我可能做错了,因为我正在使用React.

iar*_*iga 145

使用React时,不应该直接改变状态.如果Array更改了对象(或者也是对象),则应创建新副本.

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

最容易用于Array.prototype.filter()创建新阵列:

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

  • 是的,这是声明性的方式.使用prevState和箭头函数的另一种方法:`this.setState(prevState =>({people:prevState.people.filter(person => person!== e.target.value)}));` (27认同)
  • 这应该是根据从不变异状态的React习语所接受的答案. (7认同)
  • 或者使用索引:`this.state.people.filter((_,i)=> i!== index)` (7认同)
  • 有不可变的切片和可变的拼接 (2认同)
  • 我第二个@lux这应该是正确的答案 (2认同)
  • 这个答案的问题是,如果您有多个同名的人,您将删除所有这些人。在您可能受骗的情况下,使用索引更安全 (2认同)

Mar*_*coS 114

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

array.splice(index, 1);
Run Code Online (Sandbox Code Playgroud)

在你的情况下:

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});
  }
},
Run Code Online (Sandbox Code Playgroud)

  • 使用React时,通常应避免直接改变您的状态.你应该创建一个新的数组并使用`setState()`. (46认同)
  • 在这种情况下,我建议使用 Array.from(this.state.items) 而不是扩展运算符。这是因为 Array.from 专门用于此用途。 (3认同)
  • 小建议,在拼接数组之前添加对“index !== -1”的检查,以防止不需要的删除。 (3认同)
  • 在我的例子中它是:`array.splice(array,1);`谢谢 (2认同)
  • 这是反模式的。splice 函数变异或改变相同 (2认同)

wil*_*maz 41

使用slice 不改变状态的简单解决方案

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


Dmi*_*try 31

以下是Aleksandr Petrov使用ES6的回应的一个小变化

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


Hid*_*man 23

filter方法是在不触及状态的情况下修改数组的最佳方法。

它根据条件返回一个新数组。

在您的情况下,过滤器检查条件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>
Run Code Online (Sandbox Code Playgroud)

不建议:但是如果您没有任何 id,您也可以使用条件的项目索引。

index !== itemIndex


Ray*_*yon 15

用于.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);
Run Code Online (Sandbox Code Playgroud)

  • 确保不要使用拼接或任何直接更改状态变量的方法。相反,您需要创建数组的副本,从副本中删除该项目,然后将副本传递到setState中。其他答案包含有关如何执行此操作的详细信息。 (2认同)

ANK*_*OJA 6

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

当任何数据从数据库和更新列表中删除而没有API调用时,您将delete 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)
        })
      }
  
}
Run Code Online (Sandbox Code Playgroud)

  • 您能解释一下这与这个三年前问题的其他 8 个答案有何不同吗?[来自评论](https://stackoverflow.com/review/low-quality-posts/22538175) (2认同)

Ame*_* NM 6

这是您当前的状态变量:

const [animals, setAnimals] = useState(["dogs", "cats", ...])
Run Code Online (Sandbox Code Playgroud)

调用此函数并传递您要删除的项目。

removeItem("dogs")

const removeItem = (item) => {
    setAnimals((prevState) =>
      prevState.filter((prevItem) => prevItem !== item)
    );
  };
Run Code Online (Sandbox Code Playgroud)

你的状态变量现在变成:

["cats", ...]
Run Code Online (Sandbox Code Playgroud)

另一种方法是使用useState钩子。检查文档: https: //reactjs.org/docs/hooks-reference.html#function-updates它指出:与类组件中的 setState 方法不同,useState 不会自动合并更新对象。您可以通过将函数更新器形式与对象扩展语法相结合来复制此行为,如下所示或使用useReducer钩子。

const [state, setState] = useState({});
setState(prevState => {
  return {...prevState, ...updatedValues};
});
Run Code Online (Sandbox Code Playgroud)