Eliminar elemento de la matriz de estado en reaccionar

130

La historia es que debería poder poner a Bob, Sally y Jack en una caja. También puedo quitar cualquiera de la caja. Cuando se quita, no queda ninguna ranura.

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

Ahora necesito eliminar, digamos, "Bob". La nueva matriz sería:

["Sally", "Jack"]

Aquí está mi componente de reacción:

...

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

...

Aquí les muestro un código mínimo ya que hay más (onClick, etc.). La parte clave es eliminar, eliminar, destruir "Bob" de la matriz, pero removePeople()no funciona cuando se llama. ¿Algunas ideas? Estaba viendo esto, pero podría estar haciendo algo mal ya que estoy usando React.

Sylar
fuente

Respuestas:

169

Para eliminar un elemento de una matriz, simplemente haga:

array.splice(index, 1);

En tu caso:

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
fuente
2
En mi caso fue: array.splice(array, 1);Gracias
Sylar
array.splice(array, 1);? Supongo que necesitas editarlo ... Deberías usar diferentes variables ...
Rayon
61
Al usar React, generalmente debe evitar mutar su estado directamente. Debería crear una nueva matriz y usar setState().
iaretiga
2
Recomiendo usar Array.from (this.state.items) en lugar del operador de propagación en este caso. Esto se debe a que Array.from está diseñado específicamente para este uso.
Francisco Hodge
2
Pequeña sugerencia, agregue una marca de "index! == -1" antes de empalmar la matriz para evitar eliminaciones no deseadas.
RoboBear
204

Cuando use React, nunca debe mutar el estado directamente. Si Arrayse cambia un objeto (o , que también es un objeto), debe crear una nueva copia.

Otros han sugerido usarlo Array.prototype.splice(), pero ese método muta el Array, por lo que es mejor no usarlo splice()con React.

Más fácil de usar Array.prototype.filter()para crear una nueva matriz:

removePeople(e) {
    this.setState({people: this.state.people.filter(function(person) { 
        return person !== e.target.value 
    })});
}
iaretiga
fuente
42
Sí, esta es una forma declarativa. Un método alternativo que usa prevState y las funciones de flecha:this.setState(prevState => ({ people: prevState.people.filter(person => person !== e.target.value) }));
Josh Morel
9
Esta debería ser la respuesta aceptada según el idioma de React de estado nunca mutante.
lux
9
o usando el índice:this.state.people.filter((_, i) => i !== index)
mb21
2
hay un corte que es imutable y un empalme que mutable
Cassian
El problema con esta respuesta es que si tiene varias personas con el mismo nombre, las eliminará todas. Utilizando el índice es más seguro en los casos en que pueda tener duplicados
klugjo
40

Aquí hay una variación menor en la respuesta de Aleksandr Petrov usando ES6

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

Úselo .splicepara eliminar el elemento de la matriz. Usando delete, los índices de la matriz no se alterarán, pero el valor del índice específico seráundefined

El método splice () cambia el contenido de una matriz eliminando elementos existentes y / o agregando elementos nuevos.

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

Editar:

Como lo señaló justin-grant , como regla general, nunca mutes this.statedirectamente, ya que llamar setState()después puede reemplazar la mutación que hiciste. Trátelo this.statecomo si fuera inmutable.

La alternativa es crear copias de los objetos this.statey manipular las copias, asignándolas de nuevo usando setState(). Array#map, Array#filteretc.podrían utilizarse.

this.setState({people: this.state.people.filter(item => item !== e.target.value);});
Seda artificial
fuente
3
Asegúrese de no utilizar empalmes o cualquier método que cambie su variable de estado directamente. En su lugar, querrá hacer una copia de la matriz, eliminar el elemento de la copia y luego pasar la copia a setState. Otras respuestas tienen detalles sobre cómo hacer esto.
Justin Grant
12

Manera fácil de eliminar el elemento de la matriz de estado en reaccionar:

cuando cualquier dato se borra de la base de datos y actualiza la lista sin llamar a la API esa vez, pasa la identificación eliminada a esta función y esta función elimina los borrados registrados de la lista

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
fuente
1
¿Puede explicar en qué se diferencia de las otras 8 respuestas a esta pregunta de tres años? De la revisión
Wai Ha Lee
en el código anterior, volverá a crear una nueva matriz de datos pero omitirá "deletePostId" esta identificación
ANKIT-DETROJA
usoitem.post_id !== deletePostId
Nimish goel
3

Algunas respuestas mencionaron el uso de 'empalme', lo que hizo que Chance Smith mutara la matriz. Le sugiero que use la llamada al método 'slice' (el documento para 'slice' está aquí) que hace una copia de la matriz original.

Arthur Chen
fuente
3

Es muy simple Primero, define un valor

state = {
  checked_Array: []
}

Ahora,

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
fuente
1

Olvidaste usar setState. Ejemplo:

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

Pero es mejor usarlo filterporque no muta la matriz. Ejemplo:

removePeople(e){
  var array = this.state.people.filter(function(item) {
    return item !== e.target.value
  });
  this.setState({
    people: array
  })
},
Aleksandr Petrov
fuente
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 para más información

Gibbs
fuente