Mise à jour d'un objet avec setState à Réagir
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 ce:
this.setState({jasper: {name: 'someothername'}})
Les premiers résultats dans une erreur de syntaxe et le deuxième, juste ne fait rien. Des idées?
- deuxième code aurait travaillé toutefois, vous auriez perdu la
age
de la propriété à l'intérieur dejasper
.
Vous devez vous connecter pour publier un commentaire.
Il y a plusieurs manières de le faire, depuis que l'état de mise à jour est un opération asynchrone, afin de mettre à jour l'état de l'objet, nous avons besoin d'utiliser la fonction de mise à jour avec
setState
.1 - la plus Simple:
D'abord créer une copie de
jasper
puis effectuez les modifications suivantes:Au lieu d'utiliser
Object.assign
on peut aussi l'écrire comme ceci:2 - à l'Aide de la propagation de l'opérateur:
Remarque:
Object.assign
etSpread Operator
crée seulement la copie superficielle, donc si vous avez défini imbriquée objet ou groupe d'objets, vous avez besoin d'une approche différente.Mise à jour imbriquée d'état de l'objet:
Supposons que vous ayez défini comme état:
De mettre à jour extraCheese de pizza objet:
La mise à jour de tableau d'objets:
Permet de supposer que vous avez des choses à faire application, et vous gérez les données de ce formulaire:
De mettre à jour le statut de todo objet, exécutez une carte sur le tableau et vérifier une valeur unique de chaque objet, en cas de
condition=true
, retour le nouvel objet avec la valeur mise à jour, sinon même objet.Suggestion: Si l'objet n'a pas une valeur unique, alors l'utilisation d'index de tableau.
jasper
objet, ne leconsole.log(jasper)
vous verrez qu'une cléname
, l'âge ne sera pas là 🙂jasper
est unobject
, n'est pas la question de savoir si le meilleur ou non, peut-être d'autres de meilleures solutions sont possibles 🙂Object.assign
ni les diffuser opérateur de copie en profondeur les propriétés. De cette façon, vous devez utiliser des solutions de contournement comme lodashdeepCopy
etc.jasper.name = 'someothername';
n'affectera pas l'objet d'origine. mieux vaut essayer la même chose dans la console et voir le résultat 🙂jasper
avait de l'objet à l'intérieur puis de modifier cet objet ne serait pas correctname
et de l'utiliser comme suit:jasper.name: name
let { jasper } = this.state
?JSON.parse(JSON.stringify(nestedObjToCopy))
C'est la manière la plus rapide et la plus lisible:
Même si
this.state.jasper
contient déjà un nom de propriété, le nouveau nomname: 'someothername'
à être utilisé.this.state.jasper
ne contient pas nécessairement l'état le plus récent. Mieux utiliser la notation avec leprevState
.L'utilisation de la propagation de l'opérateur et de certains ES6 ici
J'ai utilisé cette solution.
Si vous avez un état imbriqué comme ceci:
vous pouvez déclarer la handleChange fonction qui copie l'état actuel et de ré-attribue avec les valeurs modifiées
ici le code html avec l'écouteur d'événement. Assurez-vous d'utiliser le même nom utilisé dans l'état de l'objet (dans ce cas friendName')
essayez cela,il devrait fonctionner correctement
Object.assign({}, this.state.jasper, {name:'someOtherName'})
Le premier cas, c'est en effet une erreur de syntaxe.
Puisque je ne peux pas voir le reste de votre composant, il est difficile de voir pourquoi vous êtes imbrication des objets dans votre état ici. Ce n'est pas une bonne idée d'imbriquer les objets dans l'état des composants. Essayez de régler votre état initial de l'être:
De cette façon, si vous voulez mettre à jour le nom, vous pouvez les appeler:
Va réaliser que ce que vous visez?
Pour les plus grands, de plus en plus complexe de magasins de données, je voudrais utiliser quelque chose comme Redux. Mais c'est beaucoup plus avancé.
La règle générale avec l'état des composants est à utiliser uniquement pour gérer l'INTERFACE utilisateur de l'état du composant (par exemple, active, timers, etc.)
Découvrez ces références:
Une autre option: définir votre variable de la Jasper objet et puis il suffit d'appeler une variable.
Propagation de l'opérateur: ES6
Vous pouvez essayer avec ce:
(Note: nom de la balise input === champ de l'objet)
Je sais qu'il y a beaucoup de réponses ici, mais je suis surpris aucun d'entre eux de créer une copie du nouvel objet à l'extérieur de setState, et puis tout simplement setState({newObject}). Propre, concis et fiable. Donc dans ce cas:
JS:
Ou pour une propriété dynamique (très utile pour les formulaires)
JS:
Aussi, à la suite d'Alberto Piras solution, si vous ne voulez pas copier tout "l'état" de l'objet:
Vous pouvez essayer ceci:
ou pour d'autres propriétés:
Ou vous pouvez utiliser handleChage fonction:
et le code HTML:
De manière Simple et dynamique.
Cela va faire le travail, mais vous devez configurer tous les id pour le parent, le parent doit pointer vers le nom de l'objet, étant id = "jasper", et le nom de l'élément input = propriété à l'intérieur de l'objet jasper.
Sans l'aide de Async et Await Utiliser ce...
Si vous utilisez avec Async Et Await utiliser ce...
c'est une autre solution à l'aide de immer immutabe utilitaire, très adapté pour la profondément imbriqués les objets avec facilité, et vous ne devriez pas vous soucier de mutation