Est-il possible de mettre à jour les propriétés de l'objet 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'}})
Le premier entraîne une erreur de syntaxe et le second ne fait rien. Des idées?
age
propriété à l'intérieurjasper
.Réponses:
Il existe plusieurs façons de le faire, car la mise à jour de l'état est une opération asynchrone , donc pour mettre à jour l'objet d'état, nous devons utiliser la fonction de mise à jour avec
setState
.1- Le plus simple:
Créez d'abord une copie de
jasper
puis effectuez les modifications suivantes:Au lieu d'utiliser,
Object.assign
nous pouvons également l'écrire comme ceci:2- Utilisation de l' opérateur d'étalement :
Remarque:
Object.assign
etSpread Operator
crée uniquement une copie superficielle , donc si vous avez défini un objet imbriqué ou un tableau d'objets, vous avez besoin d'une approche différente.Mise à jour de l'objet d'état imbriqué:
Supposons que vous ayez défini l'état comme:
Pour mettre à jour l'objet ExtraCheese of pizza:
Mise à jour du tableau d'objets:
Supposons que vous ayez une application todo et que vous gérez les données sous cette forme:
Pour mettre à jour le statut de tout objet todo, exécutez une carte sur le tableau et vérifiez la valeur unique de chaque objet, dans le cas contraire
condition=true
, renvoyez le nouvel objet avec la valeur mise à jour, sinon le même objet.Suggestion: si l'objet n'a pas de valeur unique, utilisez un index de tableau.
la source
jasper
objet, faites-le,console.log(jasper)
vous ne verrez qu'une seule cléname
, l'âge ne sera pas là :)jasper
c'est le cas, n'estobject
-ce pas le meilleur ou le non, peut-être d'autres meilleures solutions sont possibles :)Object.assign
ni propager les propriétés de copie profonde de l'opérateur. De cette façon, vous devez utiliser des solutions de contournement comme lodash,deepCopy
etc.let { jasper } = this.state
?C'est le moyen le plus rapide et le plus lisible:
Même s'il
this.state.jasper
contient déjà une propriété de nom, le nouveau nom doitname: 'someothername'
être utilisé.la source
this.state.jasper
ne contient pas nécessairement le dernier état. Mieux vaut utiliser la notation avec leprevState
.Utilisez l'opérateur d'étalement et certains ES6 ici
la source
J'ai utilisé cette solution.
Si vous avez un état imbriqué comme celui-ci:
vous pouvez déclarer la fonction handleChange qui copie l'état actuel et le réaffecte avec des valeurs modifiées
ici le html avec l'écouteur d'événement. Assurez-vous d'utiliser le même nom que celui utilisé dans l'objet d'état (dans ce cas, 'friendName')
la source
statusCopy.formInputs[inputName] = inputValue;
Je sais qu'il y a beaucoup de réponses ici, mais je suis surpris qu'aucun d'entre eux ne crée une copie du nouvel objet en dehors de setState, puis simplement setState ({newObject}). Propre, concis et fiable. Donc dans ce cas:
Ou pour une propriété dynamique (très utile pour les formulaires)
la source
essayez ça, ça devrait marcher
la source
Object.assign({}, this.state.jasper, {name:'someOtherName'})
Le premier cas est en effet une erreur de syntaxe.
Étant donné que je ne peux pas voir le reste de votre composant, il est difficile de voir pourquoi vous imbriquez des objets dans votre état ici. Ce n'est pas une bonne idée d'imbriquer des objets dans l'état du composant. Essayez de définir votre état initial sur:
De cette façon, si vous souhaitez mettre à jour le nom, vous pouvez simplement appeler:
Cela permettra-t-il d'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:
la source
Autre option: définissez votre variable hors de l' objet Jasper puis appelez simplement une variable.
Opérateur d'étalement: ES6
la source
Manière simple et dynamique.
Cela fera le travail, mais vous devez définir tous les identifiants sur le parent afin que le parent pointe vers le nom de l'objet, étant id = "jasper" et nomme le nom de la propriété element = input à l'intérieur de l'objet jasper .
la source
Vous pouvez essayer avec ceci : ( Remarque : nom de la balise d'entrée === champ d'objet)
la source
c'est une autre solution utilisant l' utilitaire immer immutabe, très adaptée aux objets profondément imbriqués avec facilité, et vous ne devriez pas vous soucier de la mutation
la source
Aussi, en suivant la solution Alberto Piras, si vous ne voulez pas copier tout l'objet "état":
la source
Vous pouvez essayer avec ceci:
ou pour d'autres biens:
Ou vous pouvez utiliser la fonction handleChage:
et code HTML:
la source
Sans utiliser Async et attendre Utilisez ceci ...
Si vous utilisez avec Async And Await, utilisez ceci ...
la source
Cette configuration a fonctionné pour moi:
la source