Guter Ansatz zum Verwalten des geschachtelten Status in React

8

EDIT: Ich habe diese Frage neu geschrieben, um zu verdeutlichen, was ich möchte - danke an die Leute, die bisher geantwortet haben und mir geholfen haben, es zu verbessern.

Ich versuche zu verstehen, wie man den komplexen, verschachtelten Zustand in React am besten verwaltet, und begrenzt auch die Häufigkeit, mit der render() für Komponenten aufgerufen wird, deren Inhalt sich nicht geändert hat.

Als Hintergrund:

Angenommen, ich habe einen Zustand mit "Autoren" und "Veröffentlichungen" in einem Objekt wie diesem:

%Vor%

In diesem erfundenen Beispiel hat der Staat zwei Hauptbereiche, auf die die Schlüssel authors und publications zugreifen.

Die authors Taste führt zu einem Objekt, das mit einer ID des Autors verknüpft ist, was zu einem Objekt mit einigen Autorendaten führt.

Die publications -Schlüssel führt zu einem Objekt, das mit der ID der Publikation, die einige Publikationsdaten enthält, und einem Array von Autoren versehen ist.

Angenommen mein Status befindet sich in einer App -Komponente mit untergeordneten Komponenten wie dem folgenden Pseudo-JSX:

%Vor%

Angenommen, AuthorList hat eine Menge von untergeordneten Author -Komponenten und PublicationList hat eine Menge von untergeordneten Publication -Komponenten, die den tatsächlichen Inhalt dieser Dinge wiedergeben.

Hier ist meine Frage: Angenommen, ich möchte die bio für einen bestimmten Autor aktualisieren, aber ich möchte nicht, dass render() für alle Objekte Author und Publication aufgerufen wird, deren Inhalt sich nicht geändert hat .

Aus dieser Antwort:

ReactJS - Wird immer aufgerufen " setState "heißt?

Die render() -Funktion einer React-Komponente wird immer dann aufgerufen, wenn sich ihr Zustand oder der Zustand eines ihrer Eltern ändert - unabhängig davon, ob diese Statusänderung etwas mit den Requisiten dieser Komponente zu tun hat. Dieses Verhalten kann mit sollteComponentUpdate geändert werden.

Wie Menschen komplexen Zustand wie oben behandeln - es scheint nicht so, als ob render () auf eine große Anzahl von Komponenten bei jeder Zustandsänderung aufgerufen wird (auch wenn das resultierende gerenderte Objekt das gleiche ist und daher keine Änderung auftritt) zum eigentlichen DOM).

    
deadcode 22.11.2016, 01:53
quelle

5 Antworten

-2

Danke an jpdeatorre und daveols, dass sie mich auf Redux aufmerksam gemacht haben.

Hier ist eine Beispielanwendung (mit Tonnen von Eckenschneiden, aber es zeigt die Technik) der Verwendung von Redux, um Komponenten von Zustandsänderungen zu isolieren, die für sie irrelevant sind.

In diesem Beispiel führen die Änderungen an dem Autor Alice mit der ID 1 nicht dazu, dass Author -Komponenten, die nicht von Alice abhängen, ihren rendern () -Aufruf haben.

Dies liegt daran, dass das von Redux bereitgestellte shouldComponentUpdate für seine verbundenen reaktiven Komponenten bewertet, ob sich die Requisiten und falls relevant der Status geändert haben.

Seien Sie vorgewarnt, dass die Optimierung von Redux hier oberflächlich ist. Um festzustellen, ob oder nicht übersprungen werden soll render() Redux shouldComponentUpdate prüft, ob:

  • Die alten und neuen Requisiten sind === zueinander
  • Oder, wenn nicht, dass sie die gleichen Schlüssel haben und die Werte dieser Schlüssel sind === zueinander.

Es könnte also dazu führen, dass render() für Komponenten aufgerufen wird, deren Werte immer noch logisch äquivalent sind, die Props für diese Komponenten und ihre Schlüssel der ersten Ebene jedoch nicht mit === gleich sind. Siehe: Ссылка

Beachten Sie auch, dass um den Aufruf von render() für die "dumme" Komponente von Author zu verhindern, ich connect() es an Redux setzen musste, um die shouldComponentUpdate -Logik von Redux zu aktivieren - obwohl diese Komponente gar nichts tut mit dem Staat und liest nur seine Requisiten.

%Vor%     
deadcode 23.11.2016, 20:28
quelle
4

Hier ist eine Möglichkeit, dies effizient und lesbar mit Objektverteilungssyntax zu erreichen.

%Vor%

Bitte denken Sie daran, dass Sie einen Schlüssel als Requisite übergeben müssen, wenn Sie Elemente in jsx abbilden.

Das liegt hauptsächlich daran, dass der Abgleich (der "Diffing" -Algorithmus von React, um zu prüfen, was sich geändert hat), der reagiert, die Schlüssel für das gemappte jsx überprüft (grob gesagt, es jsx nennt).

Wie auch immer, die Verwaltung des Status in reals state / setState oder in redux ist für die "Abstimmung" irrelevant.

In beiden Fällen können Sie den Teil der verschachtelten Daten mit der Syntax "Object Spread Syntax" ändern.

Alles, was Sie für den Rest interessieren würden, ist, 'identische' Schlüssel an das gemappte jsx zu übergeben. So dass, obwohl reag rerders, es nicht versucht, dom Updates zu unnötigen Teilen zu machen, was teuer ist.

    
FurkanO 22.11.2016 02:12
quelle
2

Sie sollten einen Helfer für die Unveränderlichkeit verwenden, pro Reacts Dokumentation . Dies stellt einen Mechanismus zum Aktualisieren eines Teils des Status bereit und behandelt jedes erforderliche Klonen für Sie mit so wenig Duplizierung wie möglich.

Dies ermöglicht Ihnen etwas wie:

%Vor%

Es werden nur Komponenten neu gerendert, die von der Änderung betroffen sind.

    
Jim Stewart 22.11.2016 02:06
quelle
1

Ich denke, mit Redux würde Ihre App effizienter und einfacher zu verwalten sein.

Wenn Sie einen globalen Status haben, der als Redux-Speicher bezeichnet wird, kann jede Komponente ein Teil des Speichers abonnieren und bei Änderungen an diesen Daten erneut rendern.

In Ihrem Beispiel wäre die reduktive Art der Implementierung, dass Ihre AuthorList -Komponente das state.authors -Objekt abonnieren würde und wenn eine Komponente innerhalb oder außerhalb der AuthorList -Komponente die state.authors aktualisiert, nur die% co_de Die% -Komponente wird erneut gerendert (und diejenigen, die sie abonniert haben).

    
jpdelatorre 22.11.2016 23:26
quelle
0

Ihr Komponentenstatus sollte nur interne Statuswerte enthalten.

Sie sollten mit Redux die Speicherung komplexerer Zustände prüfen, die in mehreren Komponenten benötigt werden.

    
daveols 22.11.2016 02:04
quelle

Tags und Links