¿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 da como resultado 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 simple:
Primero cree una copia de jasper y 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 crean solo una copia superficial , por lo que si ha definido un objeto anidado o una matriz de objetos, necesita un enfoque diferente.
Suponga que ha definido el estado como:
this.state = { food: { sandwich: { capsicum: true, crackers: true, mayonnaise: true }, pizza: { jalapeno: true, extraCheese: false } } }Para actualizar extraCheese of pizza objeto:
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 } } }))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 tareas pendientes, ejecute un mapa en la matriz y verifique algún valor único de cada objeto, en 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, use 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, se utilizará el nuevo nombre name: 'someothername' .
Use el operador de propagación y algo de ES6 aquí
this.setState({ jasper: { ...this.state.jasper, name: 'something' } })