subproperty react objects array reactjs state

reactjs - objects - setstate react



ActualizaciĆ³n de un objeto con setState en React (12)

¿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?


Además, siguiendo la solución de Alberto Piras, si no desea copiar todo el objeto "estado":

handleChange(el) { let inputName = el.target.name; let inputValue = el.target.value; let jasperCopy = Object.assign({}, this.state.jasper); jasperCopy[inputName].name = inputValue; this.setState({jasper: jasperCopy}); }


El primer caso es de hecho un error de sintaxis.

Como no puedo ver el resto de su componente, es difícil ver por qué está anidando objetos en su estado aquí. No es una buena idea anidar objetos en estado componente. Intente configurar su estado inicial para que sea:

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

De esa manera, si desea actualizar el nombre, simplemente puede llamar:

this.setState({ name: ''Sean'' });

¿Logrará eso lo que busca?

Para almacenes de datos más grandes y complejos, usaría algo como Redux. Pero eso es mucho más avanzado.

La regla general con el estado del componente es usarlo solo para administrar el estado de la interfaz de usuario del componente (por ejemplo, activo, temporizadores, etc.)

Mira estas referencias:


Forma simple y dinámica.

Esto hará el trabajo, pero debe establecer todos los identificadores para el padre para que apunte al nombre del objeto, siendo id = "jasper" y nombre el nombre del elemento de entrada = propiedad dentro del objeto jasper .

handleChangeObj = ({target: { id , name , value}}) => this.setState({ [id]: { ...this.state[id] , [name]: value } });


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

1- El más simple:

Primero cree una copia de 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- Uso del operador de propagación :

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 and 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:

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 object:

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 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 si hay algún valor único de cada objeto; en caso de condition=true , devuelva el nuevo objeto con 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.


La forma más rápida y fácil de leer:

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

Aunque this.state.jasper ya contiene una propiedad de name: ''someothername'' último name: ''someothername'' .


Otra opción: defina su variable fuera del objeto Jasper y luego simplemente llame a una variable.

Operador extendido: ES6

this.state = { jasper: { name: ''jasper'', age: 28 } } let foo = "something that needs to be saved into state" this.setState(prevState => ({ jasper: { ...jasper.entity, foo } })


Puedes probar con esto:

this.setState(prevState => { prevState = JSON.parse(JSON.stringify(this.state.jasper)); prevState.name = ''someOtherName''; return {jasper: prevState} })

o para otra propiedad:

this.setState(prevState => { prevState = JSON.parse(JSON.stringify(this.state.jasper)); prevState.age = ''someOtherAge''; return {jasper: prevState} })

O puede usar la función handleChage:

handleChage(event) { const {name, value} = event.target; this.setState(prevState => { prevState = JSON.parse(JSON.stringify(this.state.jasper)); prevState[name] = value; return {jasper: prevState} }) }

y código HTML:

<input type={"text"} name={"name"} value={this.state.jasper.name} onChange={this.handleChange} /> <br/> <input type={"text"} name={"age"} value={this.state.jasper.age} onChange={this.handleChange} />


Usé esta solución.

Si tiene un estado anidado como este:

this.state = { formInputs:{ friendName:{ value:'''', isValid:false, errorMsg:'''' }, friendEmail:{ value:'''', isValid:false, errorMsg:'''' } }

puede declarar la función handleChange que copia el estado actual y la reasigna con valores cambiados

handleChange(el) { let inputName = el.target.name; let inputValue = el.target.value; let statusCopy = Object.assign({}, this.state); statusCopy.formInputs[inputName].value = inputValue; this.setState(statusCopy); }

aquí el html con el oyente de eventos. Asegúrese de utilizar el mismo nombre utilizado en el objeto de estado (en este caso, ''nombreDeAmigo'')

<input type="text" onChange={this.handleChange} " name="friendName" />


Use el operador de propagación y algunos ES6 aquí

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


prueba esto, debería funcionar bien

this.setState(Object.assign(this.state.jasper,{name:''someOtherName''}));


Puede intentar con esto : ( Nota : nombre de la etiqueta de entrada === campo del objeto)

<input name="myField" type="text" value={this.state.myObject.myField} onChange={this.handleChangeInpForm}></input> ----------------------------------------------------------- handleChangeInpForm = (e) => { let newObject = this.state.myObject; newObject[e.target.name] = e.target.value; this.setState({ myObject: newObject }) }


Sin usar Async y Await Use esto ...

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

Si usa Async And Await, use esto ...

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