2017-04-13 1 views
0

Ich arbeite an einer kleinen Anwendung, mit der Sie einige Spielstände verfolgen können.React: Wie verwenden Sie this.state in nachfolgenden setState() -Aufrufen? Wie erzwinge ich ein Update auf this.state?

Das Spiel wird zwischen zwei Spielern gespielt. Ein Spieler kann Punkte erzielen, kann aber auch bestraft werden. Anstatt die Strafe von der Punktzahl des Spielers abzuziehen, wird sie dem Spielstand seines Gegners hinzugefügt. Der Gegner sollte auch die nächste Runde bekommen.

ich Setup eine Demo, die die obige Beschreibung implementiert: https://codepen.io/anon/pen/ybLQvR

Wie Sie in der Demo sehen es nicht ganz funktioniert: wenn ein Spieler verursacht eine Strafe er den Strafstoß zugesprochen bekommt, statt seines Gegners.

Dies ist aufgrund setState innerhalb setTurn nicht sofort verarbeitet werden. setScore verwendet immer noch den 'alten' Status, in dem der Turn nicht aktualisiert wurde.

Ich bin mir bewusst, dass dies durch die Übergabe eines Callbacks an setState statt eines Objekts (siehe den kommentierten Code) behandelt werden kann, die den zuvor festgelegten Zustand übernimmt. Wenn ich das tue, funktionieren die Dinge wie erwartet.

Ich brauche jedoch den aktualisierten Wert des Status (in diesem Fall this.state.turn) in der addScore außerhalb der setState Aufruf auch. Wie würde ich das erreichen? Ich habe this.forceUpdate() vergeblich versucht.

Sollte ich den gesamten Funktionskörper von addScore in den Rückruf setState wrappen? Wie würde ich dann irgendwelche Berechnungen basierend auf this.state.turn von der addScore Methode zurückgeben, sollte ich es brauchen?

Seitliche Frage: Warum funktioniert this.forceUpdate() nicht? Wird nur die Komponente erneut gerendert, ohne die Statuswarteschlange zu verarbeiten?

Vielen Dank für Ihre Hilfe!

+0

Wenn Sie wirklich auf dem aktuellen Stand sind, um den nächsten Zustand zu ändern, dann verwenden Sie die Callback-Funktion in setState Der bessere Weg zu gehen –

+0

Danke für Ihren Kommentar, @ CallumLinington. Wenn ich also den gesamten Funktionskörper in den 'setState'-Callback umschließe, wie würde ich irgendwelche Werte aus dem Callback-Body in den' addScore'-Methodenkörper zurückgeben? Sagen wir, ich möchte einen Wert von "addScore" zurückgeben, wenn Spieler 1 eine Punktzahl von 50 erreicht. – Meldon

Antwort

1

Ich sehe, was Sie jetzt sagen. Zu meinem Verständnis, was Sie zu tun versuchen, ist sicherzustellen, dass die setState-Methode vor einer anderen setState-Methode ausgeführt wurde.

Jetzt haben die docs dies in der Sache zu sagen:

Der zweite Parameter eine optionale Callback-Funktion, die ausgeführt wird, sobald setState abgeschlossen ist und die Komponente neu gerendert wird. Im Allgemeinen wird empfohlen, stattdessen componentDidUpdate() für eine solche Logik zu verwenden.

Also durch ihre Empfehlungen sollten Sie componentDidUpdate() verwenden. Wie ist die Frage jetzt?

componentDidUpdate(prevProps, prevState) 

Das ist die Methodensignatur. So können wir hier sehen, dass der vorherige Zustand übergeben wird, und wir haben jetzt Zugriff auf den aktuellen Zustand über this.state.

Siehe codepen für die Antwort.

Grundsätzlich - ich drehte die addScore und changeTurn in Funktionen, die nur Schnipsel der setState waren.Das bedeutet, dass wir sie zusammen mit Zustandsänderungen kombinieren können, um eine atomare Operation zu machen. Und sie können wiederverwendet werden, ohne komplizierte Standardparameter für verschiedene Szenarien hinzuzufügen.

Zweitens fügte ich Funktionen hinzu, die diese Methoden anwendeten, um den Status festzulegen. Das sind die Knöpfe!

Schließlich in der componentDidUpdate Funktion gibt es jetzt eine Chance, Aktionen basierend auf der aktuellen Aktion, die ausgeführt wird, anzuwenden. Fügen Sie keinen setState für die Standardaktion hinzu, sonst erhalten Sie eine Endlosschleife der Aktualisierung ......

+0

Gute Sachen, vielen Dank! – Meldon

Verwandte Themen