Actualizando un objeto con setState en React

Resuelto JohnSnow asked hace 7 años • 23 respuestas

¿ Es posible actualizar las propiedades del objeto con setState?

Algo como:

this.state = {
   jasper: { name: 'jasper', age: 28 },
}

Yo he tratado:

this.setState({jasper.name: 'someOtherName'});

y esto:

this.setState({jasper: {name: 'someothername'}})

El primero genera un error de sintaxis y el segundo simplemente no hace nada. ¿Algunas ideas?

JohnSnow avatar Apr 26 '17 22:04 JohnSnow
Aceptado

Hay varias formas de hacer esto, ya que la actualización de estado es una operación asíncrona , por lo que para actualizar el objeto de estado, necesitamos usar la función de actualización con setState.

1- El más sencillo:

Primero cree una copia y jasperluego haga los cambios en eso:

this.setState(prevState => {
  let jasper = Object.assign({}, prevState.jasper);  // creating copy of state variable jasper
  jasper.name = 'someothername';                     // update the name property, assign a new value                 
  return { jasper };                                 // return new object jasper object
})

En lugar de usar Object.assigntambién podemos escribirlo así:

let jasper = { ...prevState.jasper };

2- Usando sintaxis extendida :

this.setState(prevState => ({
    jasper: {                   // object that we want to update
        ...prevState.jasper,    // keep all other key-value pairs
        name: 'something'       // update the value of specific key
    }
}))

Nota: Object.assign y Spread Operatorcrea solo una copia superficial , por lo que si ha definido un objeto anidado o una matriz de objetos, necesita un enfoque diferente.


Actualizando objeto de estado anidado:

Supongamos que ha definido el estado como:

this.state = {
  food: {
    sandwich: {
      capsicum: true,
      crackers: true,
      mayonnaise: true
    },
    pizza: {
      jalapeno: true,
      extraCheese: false
    }
  }
}

Para actualizar el queso extra del objeto de pizza:

this.setState(prevState => ({
  food: {
    ...prevState.food,           // copy all other key-value pairs of food object
    pizza: {                     // specific object of food object
      ...prevState.food.pizza,   // copy all pizza key-value pairs
      extraCheese: true          // update value of specific key
    }
  }
}))

Actualización de matriz de objetos:

Supongamos que tiene una aplicación de tareas pendientes y está administrando los datos de esta forma:

this.state = {
  todoItems: [
    {
      name: 'Learn React Basics',
      status: 'pending'
    }, {
      name: 'Check Codebase',
      status: 'pending'
    }
  ]
}

Para actualizar el estado de cualquier objeto de tarea, ejecute un mapa en la matriz y verifique algún valor único de cada objeto; en el caso de condition=true, devuelva el nuevo objeto con el valor actualizado; de lo contrario, el mismo objeto.

let key = 2;
this.setState(prevState => ({

  todoItems: prevState.todoItems.map(
    el => el.key === key? { ...el, status: 'done' }: el
  )

}))

Sugerencia: si el objeto no tiene un valor único, utilice el índice de matriz.

Mayank Shukla avatar Apr 26 '2017 15:04 Mayank Shukla

Esta es la forma más rápida y legible:

this.setState({...this.state.jasper, name: 'someothername'});

Incluso si this.state.jasperya contiene una propiedad de nombre, name: 'someothername'se utilizará el nuevo nombre.

mannok avatar Apr 17 '2018 02:04 mannok