Muster zum Aktualisieren mehrerer Teile des Redux-Zustands

9

Die Form meines Redux-Zustands sieht folgendermaßen aus:

%Vor%

Unter Verwendung von Mähdrescherverdichtern habe ich zwei Sätze von Reduzierstücken. Jeder handelt auf einem der Grundschlüssel des Staates. d. h. man verwaltet den Schlüssel user und den anderen Schlüssel items .

Wenn ich ein Element hinzufügen möchte, kann ich 2 Reduzierungen aufrufen, das erste wird ein neues Objekt zu items hinzufügen und das zweite wird die ID zum user.items Array hinzufügen.

Das hat einen schlechten Code-Geruch. Ich denke, dass es einen Weg geben sollte, um den Zustand beider Objekte gleichzeitig zu reduzieren. d.h. zusätzlich zu den Unterreduzierern einen Wurzelreduzierer, der auf das Wurzelobjekt einwirkt. Ist das möglich?

    
Guy 30.12.2015, 14:38
quelle

1 Antwort

18

Ich denke, was du machst ist eigentlich richtig!

Beim Absetzen einer Aktion wird ausgehend vom Wurzelreduzierer jeder "Unterreduzierer" aufgerufen, wobei der entsprechende "Unterzustand" und die Aktion an die nächste Unterreduziererschicht weitergegeben werden. Man könnte denken, dass dies kein gutes Muster ist, da jeder "Sub-Reducer" aufgerufen wird und sich bis zu jedem einzelnen Blattknoten des Zustandsbaums ausbreitet, aber das ist tatsächlich nicht der Fall!

Wenn die Aktion im Switch-Fall definiert ist, ändert der "Sub-Reducer" nur den ihm untergeordneten "Sub-State" -Teil und übergibt die Aktion möglicherweise an die nächste Schicht, aber wenn die Aktion nicht definiert ist im "Unterreduzierer" wird es nichts tun und den aktuellen "Unterzustand" zurückgeben, der die Ausbreitung stoppt.

Sehen wir uns ein Beispiel mit einem komplexeren Zustandsbaum an!

Angenommen, Sie verwenden redux-simple-router , und ich habe Ihren Fall erweitert, um komplexer zu sein (mit Daten von mehreren Benutzern), dann sieht Ihr Statusbaum möglicherweise etwa so aus:

%Vor%

Wie Sie bereits sehen, gibt es in der Statusbaumstruktur geschachtelte Ebenen. Um dies zu umgehen, verwenden wir reducer composition und das Konzept ist > Verwenden Sie combineReducer() für jede Ebene in der Statusbaumstruktur.

Also sollte Ihr Reducer in etwa so aussehen: (Um das Layer-by-Layer-Konzept zu verdeutlichen, ist dies ein Outside-In, also ist die Reihenfolge rückwärts)

erste Ebene:

%Vor%

zweite Ebene (der Entitätsteil):

%Vor%

dritte Ebene (entities.users.items):

%Vor%

wenn eine Aktion

absetzt

redux wird jeden Unterreduzierer vom rootReducer aufrufen,
passing:
currentUser: {...} sub-state und die gesamte Aktion auf currentUserReducer
entities: {users: {...}, items: {...}} und Aktion auf entitiesReducer
routing: {...} und Aktion auf routeReducer
und ...
entitiesReducer übergibt users: {...} und action an usersReducer ,
und items: {...} und Aktion bis itemsReducer

warum ist das gut?

Sie haben also erwähnt, dass es eine Möglichkeit gibt, den Wurzelreduzierer mit verschiedenen Teilen des Zustands zu behandeln, anstatt sie an separate Unterreduzierer weiterzuleiten. Aber wenn du keine Reducer-Komposition verwendest und einen riesigen Reducer schreibst, um jeden Teil des Staates zu bearbeiten, oder du deinen Status einfach in einen tief verschachtelten Baum nestest, dann wird deine App komplizierter (zB jeder User hat ein [friends] Array, oder Elemente können [tags] , etc) haben, wird es wahnsinnig kompliziert, wenn nicht unmöglich, jeden Fall herauszufinden.

Darüber hinaus macht das Aufteilen von Reduzierungen Ihre App extrem flexibel. Sie müssen nur einen case TYPE_NAME zu einem Reducer hinzufügen, um auf diese Aktion zu reagieren (solange der Reducer übergibt, dass er reduziert wird).

Wenn Sie beispielsweise nachverfolgen möchten, ob der Benutzer eine Route besucht, fügen Sie einfach case UPDATE_PATH zu Ihrem Reduzierschalter hinzu!

    
Dax Chen 30.12.2015, 18:53
quelle

Tags und Links