Actualizando un objeto con setState en React
¿ 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?
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 jasper
luego 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.assign
tambié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 Operator
crea 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.
Esta es la forma más rápida y legible:
this.setState({...this.state.jasper, name: 'someothername'});
Incluso si this.state.jasper
ya contiene una propiedad de nombre, name: 'someothername'
se utilizará el nuevo nombre.