Supprimer l'élément du tableau d'état dans react

130

L'histoire est que je devrais être capable de mettre Bob, Sally et Jack dans une boîte. Je peux également retirer l'un ou l'autre de la boîte. Lorsqu'il est retiré, aucun emplacement n'est laissé.

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

Je dois maintenant supprimer, disons, "Bob". Le nouveau tableau serait:

["Sally", "Jack"]

Voici mon composant de réaction:

...

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

...

Ici, je vous montre un code minimal car il y a plus (onClick, etc.). La partie clé est de supprimer, supprimer, détruire "Bob" du tableau mais removePeople()ne fonctionne pas lorsqu'il est appelé. Des idées? Je regardais cela mais je fais peut-être quelque chose de mal depuis que j'utilise React.

Sylar
la source

Réponses:

169

Pour supprimer un élément d'un tableau, faites simplement:

array.splice(index, 1);

Dans ton cas:

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});
  }
},
MarcoS
la source
2
Dans mon cas, c'était: array.splice(array, 1);Merci
Sylar
array.splice(array, 1);? Je suppose que vous devez le modifier ... Vous devriez utiliser différentes variables ...
Rayon
61
Lorsque vous utilisez React, vous devez généralement éviter de muter directement votre état. Vous devez créer un nouveau tableau et utiliser setState().
iaretiga
2
Je recommande d'utiliser Array.from (this.state.items) au lieu de l'opérateur spread dans ce cas. En effet, Array.from est spécifiquement destiné à cet usage.
Francisco Hodge
2
Petite suggestion, ajoutez une vérification de "index! == -1" avant de raccorder le tableau pour éviter les suppressions indésirables.
RoboBear
204

Lorsque vous utilisez React, vous ne devez jamais muter l'état directement. Si un objet (ou Array, qui est également un objet) est modifié, vous devez créer une nouvelle copie.

D'autres ont suggéré d'utiliser Array.prototype.splice(), mais cette méthode fait muter le tableau, il est donc préférable de ne pas l'utiliser splice()avec React.

Le plus simple à utiliser Array.prototype.filter()pour créer un nouveau tableau:

removePeople(e) {
    this.setState({people: this.state.people.filter(function(person) { 
        return person !== e.target.value 
    })});
}
iaretiga
la source
42
Oui, c'est une manière déclarative. Une autre méthode utilisant les fonctions prevState et flèches:this.setState(prevState => ({ people: prevState.people.filter(person => person !== e.target.value) }));
Josh Morel
9
Cela devrait être la réponse acceptée selon l'idiome React de ne jamais muter.
lux
9
ou en utilisant l'index:this.state.people.filter((_, i) => i !== index)
mb21
2
il y a une tranche imutable et une épissure qui mutable
Cassian
Le problème avec cette réponse est que si vous avez plusieurs personnes portant le même nom, vous supprimerez toutes celles-ci. L'utilisation de l'index est plus sûre dans les cas où vous pourriez avoir des dupes
klugjo
40

Voici une variation mineure de la réponse d'Aleksandr Petrov en utilisant ES6

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

Utilisez .splicepour supprimer l'élément du tableau. En utilisant delete, les index du tableau ne seront pas modifiés mais la valeur de l'index spécifique seraundefined

La méthode splice () modifie le contenu d'un tableau en supprimant des éléments existants et / ou en ajoutant de nouveaux éléments.

Syntaxe: 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);

Éditer:

Comme l'a souligné justin-grant , en règle générale, ne jamais muter this.statedirectement, car un appel setState()après peut remplacer la mutation que vous avez faite. Traitez this.statecomme s'il était immuable.

L'alternative est de créer des copies des objets dans this.stateet de manipuler les copies, en les attribuant à nouveau à l'aide de setState(). Array#map, Array#filteretc. pourraient être utilisés.

this.setState({people: this.state.people.filter(item => item !== e.target.value);});
Rayonne
la source
3
Assurez-vous de ne pas utiliser splice ou toute autre méthode qui modifie directement votre variable d'état. Au lieu de cela, vous souhaiterez faire une copie du tableau, supprimer l'élément de la copie, puis transmettre la copie dans setState. D'autres réponses ont des détails sur la façon de procéder.
Justin Grant
12

Moyen facile de supprimer l'élément du tableau d'état dans react:

lorsque des données sont supprimées de la base de données et de la liste de mise à jour sans appel d'API à ce moment-là, vous transmettez l'ID supprimé à cette fonction et cette fonction supprime les fichiers supprimés enregistrés de la liste

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

ANKIT-DETROJA
la source
1
Pouvez-vous expliquer en quoi cela diffère des 8 autres réponses sur cette question vieille de trois ans? De l'avis
Wai Ha Lee
dans le code ci-dessus, il recréera un nouveau tableau de données mais sautera "deletePostId" cet id
ANKIT-DETROJA
utilisationitem.post_id !== deletePostId
Nimish goel
3

Certaines réponses ont mentionné l'utilisation de `` splice '', ce qui a fait comme Chance Smith l'a dit a muté le tableau. Je vous suggère d'utiliser la méthode d'appel «slice» (le document pour «slice» est ici) qui fait une copie du tableau d'origine.

Arthur Chen
la source
3

C'est très simple d'abord vous définissez une valeur

state = {
  checked_Array: []
}

Maintenant,

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)
}
QC innodel
la source
1

Vous avez oublié d'utiliser setState. Exemple:

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

Mais il est préférable de l'utiliser filtercar il ne mute pas le tableau. Exemple:

removePeople(e){
  var array = this.state.people.filter(function(item) {
    return item !== e.target.value
  });
  this.setState({
    people: array
  })
},
Aleksandr Petrov
la source
1
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 pour plus d'informations

Gibbs
la source