Ist es überhaupt möglich, die Objekteigenschaften mit zu aktualisieren setState
?
Etwas wie:
this.state = {
jasper: { name: 'jasper', age: 28 },
}
Ich habe versucht:
this.setState({jasper.name: 'someOtherName'});
und das:
this.setState({jasper: {name: 'someothername'}})
Der erste führt zu einem Syntaxfehler und der zweite führt einfach zu nichts. Irgendwelche Ideen?
age
Eigenschaft im Inneren verlorenjasper
.Antworten:
Es gibt mehrere Möglichkeiten, dies zu tun, da die Statusaktualisierung eine asynchrone Operation ist. Um das Statusobjekt zu aktualisieren, müssen wir die Updater-Funktion mit verwenden
setState
.1- Einfachste:
Erstellen Sie zuerst eine Kopie von und nehmen Sie
jasper
dann die folgenden Änderungen vor:Anstatt zu verwenden
Object.assign
, können wir es auch so schreiben:2- Verwenden des Spread-Operators :
Hinweis:
Object.assign
undSpread Operator
erstellt nur eine flache Kopie . Wenn Sie also ein verschachteltes Objekt oder ein Array von Objekten definiert haben, benötigen Sie einen anderen Ansatz.Verschachteltes Statusobjekt aktualisieren:
Angenommen, Sie haben den Status wie folgt definiert:
So aktualisieren Sie extraCheese des Pizzaobjekts:
Array von Objekten aktualisieren:
Nehmen wir an, Sie haben eine ToDo-App und verwalten die Daten in folgender Form:
Um den Status eines Aufgabenobjekts zu aktualisieren, führen Sie eine Zuordnung auf dem Array aus und suchen Sie nach einem eindeutigen Wert für jedes Objekt. Geben Sie im Falle von
condition=true
das neue Objekt mit dem aktualisierten Wert zurück, andernfalls dasselbe Objekt.Vorschlag: Wenn das Objekt keinen eindeutigen Wert hat, verwenden Sie den Array-Index.
quelle
jasper
Objekt entfernen , tunconsole.log(jasper)
Sie, dass Sie nur einen Schlüssel sehenname
, Alter wird nicht da sein :)jasper
es ein istobject
, nicht das Beste oder nicht, vielleicht sind andere bessere Lösungen möglich :)Object.assign
Operator Deep Copy-Eigenschaften noch verbreiten. Auf diese Weise sollten Sie Problemumgehungen wie lodashdeepCopy
usw. verwendenlet { jasper } = this.state
?Dies ist der schnellste und am besten lesbare Weg:
Auch wenn
this.state.jasper
bereits eine Namenseigenschaft enthalten ist, wird der neue Namename: 'someothername'
verwendet.quelle
this.state.jasper
enthält nicht unbedingt den neuesten Stand. Verwenden Sie besser die Notation mit demprevState
.Verwenden Sie hier den Spread-Operator und etwas ES6
quelle
Ich habe diese Lösung verwendet.
Wenn Sie einen verschachtelten Status wie diesen haben:
Sie können die Funktion handleChange deklarieren, die den aktuellen Status kopiert und ihn mit geänderten Werten neu zuweist
hier das html mit dem event listener. Stellen Sie sicher, dass Sie denselben Namen verwenden, der auch für das Statusobjekt verwendet wird (in diesem Fall 'friendName').
quelle
statusCopy.formInputs[inputName] = inputValue;
Ich weiß, dass es hier viele Antworten gibt, aber ich bin überrascht, dass keine von ihnen eine Kopie des neuen Objekts außerhalb von setState erstellt und dann einfach setState ({newObject}). Sauber, prägnant und zuverlässig. Also in diesem Fall:
Oder für eine dynamische Eigenschaft (sehr nützlich für Formulare)
quelle
Versuchen Sie dies, es sollte gut funktionieren
quelle
Object.assign({}, this.state.jasper, {name:'someOtherName'})
Der erste Fall ist in der Tat ein Syntaxfehler.
Da ich den Rest Ihrer Komponente nicht sehen kann, ist es schwer zu verstehen, warum Sie hier Objekte in Ihrem Status verschachteln. Es ist keine gute Idee, Objekte im Komponentenstatus zu verschachteln. Versuchen Sie, Ihren Ausgangszustand wie folgt einzustellen:
Auf diese Weise können Sie, wenn Sie den Namen aktualisieren möchten, einfach Folgendes aufrufen:
Wird das das erreichen, was Sie anstreben?
Für größere, komplexere Datenspeicher würde ich so etwas wie Redux verwenden. Aber das ist viel weiter fortgeschritten.
Die allgemeine Regel für den Komponentenstatus lautet, ihn nur zum Verwalten des Benutzeroberflächenstatus der Komponente zu verwenden (z. B. aktiv, Timer usw.).
Schauen Sie sich diese Referenzen an:
quelle
Eine weitere Option: Definieren Sie Ihre Variable aus dem Jasper- Objekt heraus und rufen Sie dann einfach eine Variable auf.
Spread-Operator: ES6
quelle
Einfache und dynamische Art und Weise.
Dies erledigt den Job, aber Sie müssen alle IDs auf das übergeordnete Element setzen, damit das übergeordnete Element auf den Namen des Objekts zeigt, dh id = "jasper", und den Namen der Eigenschaft input element = innerhalb des Objektjasper benennt .
quelle
Sie können Folgendes versuchen : ( Hinweis : Name des Eingabe-Tags === Feld des Objekts)
quelle
Dies ist eine weitere Lösung, die das Dienstprogramm immer immutabe verwendet und sich sehr gut für tief verschachtelte Objekte eignet. Sie sollten sich nicht um Mutationen kümmern
quelle
Wenn Sie nach der Alberto Piras-Lösung nicht das gesamte "Status" -Objekt kopieren möchten:
quelle
Sie können dies versuchen:
oder für andere Eigenschaft:
Oder Sie können die handleChage-Funktion verwenden:
und HTML-Code:
quelle
Ohne Async und Await zu verwenden Verwenden Sie diese ...
Wenn Sie mit Async And Await verwenden, verwenden Sie diese ...
quelle
Dieses Setup hat bei mir funktioniert:
quelle