2016-05-30 3 views
12

Ich bin neu in Redux - und ich versuche wirklich, das große Bild der Verwendung der funktionalen Programmierung zu bekommen, um unidirektionale Daten eleganter zu machen.Redux: Warum ist die Vermeidung von Mutationen so ein grundlegender Bestandteil der Verwendung?

Die Art, wie ich es sehe - jeder Reducer nimmt den alten Zustand, schafft einen neuen Zustand, ohne den alten Zustand zu mutieren und dann den neuen Zustand an den nächsten Reducer weiterzugeben, um dasselbe zu tun.

Ich bekomme, dass keine Nebenwirkungen verursacht, hilft uns, die Vorteile eines unidirektionalen Datenflusses zu erhalten.

Ich verstehe nur wirklich nicht, was so wichtig ist, den alten Staat nicht zu mutieren.

Das einzige, was mir einfällt, ist vielleicht das "Zeitreisen", von dem ich gelesen habe, denn wenn man an jedem Staat festhält, kann man "rückgängig machen".

Frage:

Gibt es andere Gründe, warum wir nicht wollen, den alten Zustand bei jedem Schritt mutieren?

Antwort

16

Die Arbeit mit unveränderlichen Datenstrukturen kann sich positiv auf die Leistung auswirken, wenn dies richtig gemacht wird. Im Fall von React besteht die Leistung häufig darin, unnötige Neu-Renderings Ihrer App zu vermeiden, wenn sich die Daten nicht ändern.

Um dies zu erreichen, müssen Sie den nächsten Status Ihrer App mit dem aktuellen Status vergleichen. Wenn sich die Zustände unterscheiden: Rendern. Ansonsten nicht.

Um Zustände zu vergleichen, müssen Sie die Objekte im Status auf Gleichheit vergleichen. In einfachen alten JavaScript-Objekten müssten Sie einen tiefen Vergleich durchführen, um zu sehen, ob sich eine Eigenschaft in den Objekten geändert hat.

Mit unveränderlichen Objekten brauchen Sie das nicht.

immutableObject1 === immutableObject2 

tut im Grunde den Trick. Oder wenn Sie eine Lib wie Immutable.js Immutable.is(obj1, obj2) verwenden.

In Bezug auf reagieren können Sie es für die Methode verwenden, wie die beliebte PureRenderMixin tut.

shouldComponentUpdate(nextProps, nextState) { 
    return nextState !== this.state; 
} 

Diese Funktion verhindert das erneute Rendern, wenn sich der Status nicht geändert hat.

Ich hoffe, dass dies zu den Gründen für unveränderliche Objekte beiträgt.

+0

Bis jetzt ist dies die beste Antwort auf den Kern der Frage.Wie ich schon sagte - "Ich bekomme, dass Nebenwirkungen, die keine Nebenwirkungen verursachen, uns helfen, die Vorteile eines unidirektionalen Datenflusses zu nutzen. Ich verstehe wirklich nicht, was so wichtig ist, wenn man den alten Zustand nicht mutiert." –

+1

Warum? Das ist nicht die akzeptierte Antwort? Kurz gesagt, wenn Sie Objekte mutieren, können Sie den folgenden Vergleich nicht durchführen: immutableObject1 === immutableObject2. Stattdessen müssen Sie einen tiefen Vergleich durchführen, um festzustellen, ob sich eine Eigenschaft in den Objekten geändert hat. – Antoni4

4

Ich bin ziemlich neu zu Redux (und React.js) auch, aber das ist, was ich aus dem Lernen dieses Zeug verstehe.

Es gibt mehrere Gründe, warum der unveränderliche Zustand gegenüber dem änderbaren gewählt wird. Erstens, Mutation Tracking ist ziemlich schwierig. Wenn Sie beispielsweise eine Variable in mehreren Codeabschnitten verwenden und die Variable an jeder dieser Stellen geändert werden kann, müssen Sie jede Änderung behandeln und die Ergebnisse der Mutation synchronisieren. Dieser Ansatz führt in vielen Fällen zu bidirektionalen Datenflüssen. Datenstücke fließen über die Funktionen, Variablen und so weiter. Der Code beginnt mit if-else Konstruktionen, die nur für die Handhabung von Zustandsänderungen verantwortlich sind. Wenn Sie einige asynchrone Aufrufe hinzufügen, können Statusänderungen möglicherweise noch schwieriger zu verfolgen sein. Natürlich können wir Datenereignisse abonnieren (zum Beispiel Object.observe), aber es kann dazu führen, dass ein Teil der Anwendung, der die Änderung verpasst hat, nicht mit anderen Teilen Ihres Programms synchronisiert ist.

Der unveränderbare Status hilft Ihnen bei der Implementierung eines unidirektionalen Datenflusses, der Ihnen hilft, alle Änderungen zu verarbeiten. Zunächst fließen Daten von oben nach unten. Das bedeutet, dass alle Änderungen, die auf das Hauptmodell angewendet wurden, auf die unteren Komponenten übertragen werden. Sie können immer sicher sein, dass der Status an allen Stellen der Anwendung gleich ist, da er nur von einer Stelle in den Code-Reducern geändert werden kann. Es gibt auch eine erwähnenswerte Sache - Sie können Daten in mehreren Komponenten wiederverwenden. Der Status kann nicht geändert werden (es kann ein neuer erstellt werden), daher ist es ziemlich sicher, an mehreren Stellen dieselben Daten zu verwenden.

können Sie weitere Informationen über Vor- und Nachteile der Veränderlichkeit (und über den Grund, warum es als Haupt Ansatz von Redux gewählt wurde) finden Sie hier:

0

Keine Gründe. Es gibt keine grundsätzlichen Gründe, warum die "pure render" -Optimierung vonComponentUpdate nicht mit veränderbaren Statuscontainern funktionieren kann. Diese Bibliothek macht es zum Beispiel.

https://github.com/Volicon/NestedReact

Mit dem Verweis auf die Datenstruktur selbst unveränderlichen Daten können als Version Token verwendet werden. Vergleicht man die Referenzen, vergleicht man die Versionen.

Mit veränderbaren Daten müssen Sie separate Versions-Tokens einführen (und vergleichen), was manuell schwierig ist, aber leicht mit intelligenten "beobachtbaren" Objekten erreicht werden kann.

3

Redux überprüft, ob das alte Objekt dem neuen Objekt entspricht, indem es die Speicherpositionen der beiden Objekte vergleicht. Wenn Sie die Eigenschaft des alten Objekts innerhalb eines Reduzierers mutieren, zeigen der "neue Zustand" und der "alte Zustand" beide auf dasselbe Objekt und Redux wird daraus schließen, dass sich nichts geändert hat.

0

Der Schlüssel des "No-Mutations" -Mantras ist, dass Wenn Sie das Objekt nicht mutieren können, müssen Sie einen neuen (mit den Eigenschaften des ursprünglichen Objekts plus die neuen) erstellen. Um die Komponenten zu aktualisieren, wenn eine Aktion ausgelöst wird, prüft Redux, wenn das Objekt unterschiedlich ist, nicht, wenn die Eigenschaften geändert haben, so:

  • Wenn Sie ein neues Objekt erstellen , Redux werden sehen, dass das Objekt nicht das gleiche, so wird es die Komponenten Updates auslösen.
  • Wenn Sie das objet mutieren , dass es bereits im Speicher ist (Hinzufügen oder Entfernen eine Eigenschaft zu ändern, zum Beispiel) Redux nicht sieht die Änderung, so wird es nicht um die Komponenten zu aktualisieren.
Verwandte Themen