Mettre à jour un object avec setState dans React

Est-il possible de mettre à jour les propriétés de l’object avec setState?

Quelque chose comme:

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

J’ai essayé:

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

et ça:

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

La première est une erreur de syntaxe et la seconde ne fait rien. Des idées?

Il y a plusieurs façons de le faire.

1- Le plus simple:

Commencez par créer une copie de jasper puis effectuez les modifications suivantes:

 let jasper = Object.assign({}, this.state.jasper); //creating copy of object jasper.name = 'someothername'; //updating value this.setState({jasper}); 

Au lieu d’utiliser Object.assign nous pouvons également l’écrire comme ceci:

 let jasper = {...this.state.jasper}; 

2- En utilisant un opérateur de spread :

 this.setState(prevState => ({ jasper: { ...prevState.jasper, name: 'something' } })) 

Le moyen le plus rapide et le plus lisible:

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

Bien que this.state.jasper contienne déjà une propriété name, ce dernier name: 'someothername' soit utilisé.

J’ai utilisé cette solution.

Si vous avez un état nested comme celui-ci:

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

vous pouvez déclarer la fonction handleChange qui copie le statut actuel et la réaffecte avec des valeurs modifiées

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

ici le HTML avec l’écouteur d’événement. Assurez-vous d’utiliser le même nom que celui utilisé dans l’object state (dans ce cas, “friendName”)

  

Le premier cas est en effet une erreur de syntaxe.

Comme je ne peux pas voir le rest de votre composant, il est difficile de voir pourquoi vous nichez des objects dans votre état ici. Ce n’est pas une bonne idée d’imbriquer des objects dans l’état du composant. Essayez de définir votre état initial pour être:

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

De cette façon, si vous souhaitez mettre à jour le nom, vous pouvez simplement appeler:

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

Cela va-t-il atteindre ce que vous visez?

Pour les magasins de données plus grands et plus complexes, j’utiliserais quelque chose comme Redux. Mais c’est beaucoup plus avancé.

La règle générale avec l’état du composant est de l’utiliser uniquement pour gérer l’état de l’interface utilisateur du composant (par exemple, actif, temporisateurs, etc.)

Découvrez ces références:

Utilisez l’opérateur de diffusion et certains ES6 ici

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

Aussi, suite à la solution d’Alberto Piras, si vous ne voulez pas copier tout l’object “state”:

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

Autre option: définissez votre variable à partir de l’object Jasper , puis appelez simplement une variable.

Opérateur de diffusion: 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 } })