Gibt es einen systematischen Ansatz zum Debuggen, was dazu führt, dass eine Komponente in React neu gerendert wird? Ich habe ein einfaches console.log () eingefügt, um zu sehen, wie oft es gerendert wird, aber ich habe Probleme herauszufinden, warum die Komponente in meinem Fall mehrmals, dh (viermal) gerendert wird. Gibt es ein Tool, das eine Zeitleiste und / oder das Rendern und die Reihenfolge aller Komponentenbäume anzeigt?
154
shouldComponentUpdate
automatische Komponentenaktualisierung deaktivieren und dann von dort aus Ihre Ablaufverfolgung starten. Weitere Informationen finden Sie hier: facebook.github.io/react/docs/optimizing-performance.htmlAntworten:
Wenn Sie ein kurzes Snippet ohne externe Abhängigkeiten möchten, finde ich dies nützlich
Hier ist ein kleiner Hook, mit dem ich Aktualisierungen von Funktionskomponenten nachverfolge
quelle
setState
Methode (in einer Klassenkomponente) überschreibensetState(...args) { super.setState(...args) }
und dann in Ihrem Debugger einen Haltepunkt festlegen, den Sie dann aktivieren können um zu der Funktion zurückzukehren, die den Zustand einstellt.useTraceUpdate
nachdem ich es so definiert habe, wie Sie es geschrieben haben?function MyComponent(props) { useTraceUpdate(props); }
folgt verwenden und sie wird protokolliert, wenn sich die Requisiten ändernthis.state
ist also undefiniert.In den folgenden Fällen wird eine React-Komponente erneut gerendert.
this.setState()
innerhalb der Komponente. Dadurch werden die folgenden Komponenten Lifecycle Methoden auslösenshouldComponentUpdate
>componentWillUpdate
>render
>componentDidUpdate
props
. Dies wird TriggercomponentWillReceiveProps
>shouldComponentUpdate
>componentWillUpdate
>render
>componentDidUpdate
(connect
Methode derreact-redux
Trigger dies , wenn es anwendbar Änderungen in dem Redux - Shop)this.forceUpdate
der ähnlich ist wiethis.setState
Sie können das Rendern Ihrer Komponente minimieren, indem Sie eine Prüfung in Ihrer Komponente implementieren
shouldComponentUpdate
und diese zurückgeben,false
wenn dies nicht erforderlich ist.Eine andere Möglichkeit ist die Verwendung von
React.PureComponent
oder zustandslosen Komponenten. Reine und zustandslose Komponenten werden nur dann neu gerendert, wenn Änderungen an den Requisiten vorgenommen wurden.quelle
shouldComponentUpdate
oder erweiternReact.PureComponent
, um nur das erneute Rendern bei Änderungen zu erzwingen.const MyComponent = (props) => <h1>Hello {props.name}</h1>;
(das ist eine zustandslose Komponente). Es wird immer wieder neu gerendert, wenn die übergeordnete Komponente erneut gerendert wird.Die Antwort von @ jpdelatorre ist großartig, um allgemeine Gründe hervorzuheben, warum eine React-Komponente möglicherweise neu gerendert wird.
Ich wollte nur etwas tiefer in eine Instanz eintauchen: Wenn sich die Requisiten ändern . Die Fehlerbehebung, die dazu führt, dass eine React-Komponente erneut gerendert wird, ist ein häufiges Problem. Nach meiner Erfahrung müssen Sie häufig feststellen, welche Requisiten geändert werden, um dieses Problem aufzuspüren .
Reagieren Sie darauf, dass Komponenten neu gerendert werden, wenn sie neue Requisiten erhalten. Sie können neue Requisiten erhalten wie:
<MyComponent prop1={currentPosition} prop2={myVariable} />
oder wenn
MyComponent
mit einem Redux-Speicher verbunden ist:Immer wenn der Wert
prop1
,prop2
,prop3
, oderprop4
ÄnderungenMyComponent
werden wieder machen. Mit 4 Requisiten ist es nicht allzu schwierig herauszufinden, welche Requisiten sich ändern, indem Sieconsole.log(this.props)
an diesem Anfang desrender
Blocks ein setzen. Bei immer komplizierteren Komponenten und immer mehr Requisiten ist diese Methode jedoch unhaltbar.Hier ist ein nützlicher Ansatz ( zur Vereinfachung die Verwendung von lodash ), um zu bestimmen, welche Requisitenänderungen dazu führen, dass eine Komponente erneut gerendert wird:
Das Hinzufügen dieses Snippets zu Ihrer Komponente kann dazu beitragen, den Schuldigen aufzudecken, der fragwürdige Wiederholungen verursacht, und dies hilft häufig dabei, unnötige Daten zu ermitteln, die in Komponenten geleitet werden.
quelle
UNSAFE_componentWillReceiveProps(nextProps)
und ist veraltet. "Dieser Lebenszyklus wurde zuvor benanntcomponentWillReceiveProps
. Dieser Name funktioniert bis Version 17 weiter." Aus der React-Dokumentation .Seltsamerweise hat niemand diese Antwort gegeben, aber ich finde sie sehr nützlich, zumal die Änderungen der Requisiten fast immer tief verschachtelt sind.
Haken Fanboys:
"Old" -Schule-Fanboys:
PS Ich bevorzuge immer noch die Verwendung von HOC (Komponente höherer Ordnung), da Sie manchmal Ihre Requisiten oben zerstört haben und Jacobs Lösung nicht gut passt
Haftungsausschluss: Keine Zugehörigkeit zum Paketinhaber. Nur zehnmal herumzuklicken, um den Unterschied in tief verschachtelten Objekten zu erkennen, ist ein Problem.
quelle
Es gibt jetzt einen Haken dafür auf npm:
https://www.npmjs.com/package/use-trace-update
(Offenlegung, ich habe es veröffentlicht) Update: Entwickelt basierend auf Jacob Rask's Code
quelle
Bei Verwendung von Haken und Funktionskomponenten kann nicht nur der Propellerwechsel zu einem erneuten Rendern führen. Was ich zu verwenden begann, ist ein eher manuelles Protokoll. Ich habe mir sehr geholfen. Vielleicht finden Sie es auch nützlich.
Ich füge diesen Teil in die Datei der Komponente ein:
Zu Beginn der Methode behalte ich eine WeakMap-Referenz:
Dann schreibe ich nach jedem "verdächtigen" Anruf (Requisiten, Haken):
quelle
Die obigen Antworten sind sehr hilfreich, nur für den Fall, dass jemand nach einer spezifischen Methode sucht, um die Ursache für das erneute Rendern zu erkennen, fand ich diesen Bibliotheksredux-Logger sehr hilfreich.
Was Sie tun können, ist die Bibliothek hinzuzufügen und die Unterscheidung zwischen den Status (sie befindet sich in den Dokumenten) wie folgt zu aktivieren:
Und fügen Sie die Middleware im Laden hinzu.
Fügen Sie dann eine
console.log()
in die Renderfunktion der Komponente ein, die Sie testen möchten.Dann können Sie Ihre App ausführen und nach Konsolenprotokollen suchen. Wo immer es ein Protokoll gibt, kurz bevor es Ihnen den Unterschied zwischen dem Status anzeigt
(nextProps and this.props)
, können Sie entscheiden, ob dort wirklich Rendering benötigt wirdEs ähnelt dem obigen Bild zusammen mit der Diff-Taste.
quelle