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?
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:
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)
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
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!
Tags und Links javascript redux