Sie können keine der bestehenden Lebenszyklus Methoden (Verwendung componentDidMount
, componentDidUpdate
, componentWillUnmount
etc.) in einem Haken. Sie können nur in Klassenkomponenten verwendet werden. Und mit Hooks können Sie nur in Funktionskomponenten verwenden. Die folgende Zeile stammt aus dem React-Dokument:
Wenn Sie mit React Klasse Lifecycle Methoden vertraut sind, können Sie sich vorstellen useEffect
Haken wie componentDidMount
, componentDidUpdate
und componentWillUnmount
kombiniert.
Es wird vorgeschlagen, dass Sie diese Lebenszyklusmethode aus einer Klassenkomponente in einer Funktionskomponente nachahmen können.
Code im Inneren componentDidMount
wird einmal ausgeführt, wenn die Komponente bereitgestellt wird. useEffect
Hakenäquivalent für dieses Verhalten ist
useEffect(() => {
// Your code here
}, []);
Beachten Sie hier den zweiten Parameter (leeres Array). Dies wird nur einmal ausgeführt.
Ohne den zweiten Parameter wird der useEffect
Hook bei jedem Rendering der Komponente aufgerufen, was gefährlich sein kann.
useEffect(() => {
// Your code here
});
componentWillUnmount
wird zur Bereinigung verwendet (z. B. Entfernen von Ereignis-Listenern, Abbrechen des Timers usw.). Angenommen, Sie fügen einen Ereignis-Listener hinzu componentDidMount
und entfernen ihn componentWillUnmount
wie folgt.
componentDidMount() {
window.addEventListener('mousemove', () => {})
}
componentWillUnmount() {
window.removeEventListener('mousemove', () => {})
}
Das Hook-Äquivalent des obigen Codes lautet wie folgt
useEffect(() => {
window.addEventListener('mousemove', () => {});
// returned function will be called on component unmount
return () => {
window.removeEventListener('mousemove', () => {})
}
}, [])
useEffect()
Funktion wirklich , danke.componentWillMount
componentWillMount
, nichtcomponentWillUnmount
. Diese Antwort beantwortet die Frage in der Tat überhaupt nicht und wiederholt nur, was das OP bereits impliziert hat, um zu wissen.useComponentDidMount-Hook
In den meisten Fällen
useComponentDidMount
ist das Werkzeug zu verwenden. Es wird nur einmal ausgeführt, nachdem die Komponente bereitgestellt wurde (anfängliches Rendern).useComponentWillMount
Es ist wichtig zu beachten, dass Komponenten in Klassen
componentWillMount
als Legacy betrachtet werden. Wenn Sie Code nur einmal ausführen müssen, bevor die Komponente bereitgestellt wurde, können Sie den Konstruktor verwenden. Mehr dazu hier . Da die Funktionskomponente nicht die Äquivalenz eines Konstruktors hat, kann es in bestimmten Fällen sinnvoll sein, einen Hook zu verwenden, um Code nur einmal auszuführen, bevor Komponenten bereitgestellt werden. Sie können es mit einem benutzerdefinierten Haken erreichen.Es gibt jedoch eine Falle. Verwenden Sie es nicht, um Ihren Status asynchron festzulegen (z. B. nach einer Serveranforderung. Wie zu erwarten ist, wirkt sich dies auf das anfängliche Rendern aus, das nicht erfolgt). Solche Fälle sollten behandelt werden
useComponentDidMount
.Demo
Vollständige Demo
quelle
componentWillMount
basiert aufuseEffect
hat zwei Probleme. Der erste ist, dass es in funktionalen Komponenten keinen Montagelebenszyklus gibt. Beide Hooks werden ausgeführt, nachdem die Komponente gerendert wurde,Runs only once before component mounts
was irreführend ist. Die zweite ist, dasscomponentWillMount
beim Server-Rendering aufgerufen wird unduseEffect
nicht. Viele Bibliotheken verlassen sich immer noch darauf,UNSAFE_componentWillMount
da dies derzeit die einzige Möglichkeit ist, eine Nebenwirkung auf der Serverseite auszulösen.Laut reactjs.org wird componentWillMount in Zukunft nicht mehr unterstützt. https://reactjs.org/docs/react-component.html#unsafe_componentwillmount
Es ist nicht erforderlich, componentWillMount zu verwenden.
Wenn Sie etwas tun möchten, bevor die Komponente bereitgestellt wurde, tun Sie dies einfach im Konstruktor ().
Wenn Sie Netzwerkanforderungen ausführen möchten, tun Sie dies nicht in componentWillMount. Dies liegt daran, dass dies zu unerwarteten Fehlern führt.
Netzwerkanforderungen können in componentDidMount ausgeführt werden.
Ich hoffe es hilft.
aktualisiert am 08/03/2019
Der Grund, warum Sie nach componentWillMount fragen, liegt wahrscheinlich darin, dass Sie den Status vor dem Rendern initialisieren möchten.
Mach es einfach in useState.
oder vielleicht möchten Sie eine Funktion in componentWillMount ausführen, wenn Ihr ursprünglicher Code folgendermaßen aussieht:
Mit Hook müssen Sie lediglich die Lebenszyklusmethode entfernen:
Ich möchte der ersten Antwort zu useEffect nur etwas hinzufügen.
useEffect wird bei jedem Rendering ausgeführt und ist eine Kombination aus componentDidUpdate, componentDidMount und ComponentWillUnmount.
Wenn wir in useEffect ein leeres Array hinzufügen, wird es nur ausgeführt, wenn die Komponente bereitgestellt wird. Dies liegt daran, dass useEffect das Array vergleicht, das Sie an es übergeben haben. Es muss also kein leeres Array sein. Es kann sich um ein Array handeln, das sich nicht ändert. Zum Beispiel kann es [1,2,3] oder ['1,2'] sein. useEffect wird immer noch nur ausgeführt, wenn die Komponente bereitgestellt ist.
Es hängt von Ihnen ab, ob es nur einmal oder nach jedem Rendern ausgeführt werden soll. Es ist nicht gefährlich, wenn Sie vergessen haben, ein Array hinzuzufügen, solange Sie wissen, was Sie tun.
Ich habe ein Beispiel für Hook erstellt. Bitte probieren Sie es aus.
https://codesandbox.io/s/kw6xj153wr
aktualisiert am 21/08/2019
Es ist weiß, seit ich die obige Antwort geschrieben habe. Ich denke, Sie müssen auf etwas achten. Wenn Sie verwenden
Wenn reag die Werte vergleicht, die Sie an das Array [] übergeben haben, wird Object.is () zum Vergleichen verwendet. Wenn Sie ein Objekt daran übergeben, z
Dies ist genau das gleiche wie:
Es wird jedes Mal neu gerendert, da beim Vergleichen eines Objekts durch Object.is () dessen Referenz und nicht der Wert selbst verglichen wird. Es ist dasselbe wie der Grund, warum {} === {} false zurückgibt, weil ihre Referenzen unterschiedlich sind. Wenn Sie immer noch das Objekt selbst und nicht die Referenz vergleichen möchten, können Sie Folgendes tun:
quelle
useLayoutEffect
Dies könnte mit einer leeren Gruppe von Beobachtern ([]
) erreicht werden, wenn die Funktionalität tatsächlich ähnlich istcomponentWillMount
- sie wird ausgeführt, bevor der erste Inhalt in das DOM gelangt - obwohl es tatsächlich zwei Aktualisierungen gibt, die jedoch synchron sind, bevor sie auf den Bildschirm gezeichnet werden.beispielsweise:
Der Vorteil gegenüber
useState
einem Initialisierer / Setter oderuseEffect
obwohl er möglicherweise einen Render-Durchgang berechnet, gibt es keine tatsächlichen Renderings für das DOM, die ein Benutzer bemerken wird, und es wird vor dem ersten erkennbaren Rendering ausgeführt, was nicht der Fall istuseEffect
. Der Nachteil ist natürlich eine leichte Verzögerung beim ersten Rendern, da vor dem Malen auf dem Bildschirm eine Überprüfung / Aktualisierung erfolgen muss. Es hängt jedoch wirklich von Ihrem Anwendungsfall ab.Ich persönlich denke,
useMemo
ist in einigen Nischenfällen in Ordnung, in denen Sie etwas Schweres tun müssen - solange Sie bedenken, dass dies die Ausnahme gegenüber der Norm ist.quelle
Ich habe einen benutzerdefinierten Hook geschrieben, der eine Funktion vor dem ersten Rendern einmal ausführt.
useBeforeFirstRender.js
Verwendung:
quelle
So simuliere ich Konstruktoren in Funktionskomponenten mithilfe des
useRef
Hooks:Hier ist das Beispiel für den Lebenszyklus:
Natürlich haben Klassenkomponenten keine
Body
Schritte, es ist aufgrund unterschiedlicher Funktions- und Klassenkonzepte nicht möglich, eine 1: 1-Simulation durchzuführen.quelle
Es gibt eine schöne Problemumgehung zu implementieren
componentDidMount
undcomponentWillUnmount
mituseEffect
.useEffect
Kann basierend auf der Dokumentation eine "Bereinigungs" -Funktion zurückgeben. Diese Funktion wird nicht beim erstenuseEffect
Aufruf aufgerufen, sondern nur bei nachfolgenden Aufrufen.Wenn wir den
useEffect
Hook ohne Abhängigkeiten verwenden, wird der Hook daher nur aufgerufen, wenn die Komponente bereitgestellt ist, und die Funktion "Bereinigen" wird aufgerufen, wenn die Komponente nicht bereitgestellt wird.Der Funktionsaufruf für die Bereinigungsrückgabe wird nur aufgerufen, wenn die Komponente nicht bereitgestellt ist.
Hoffe das hilft.
quelle
useEffect
Anruf die gleiche FunktionalitätcomponentWillMount
undcomponentWillUnmount
auf nette und saubere Weise erhaltenuseEffect
nur nach dem Rendern ausgeführt, während escomponentWillMount
vor dem Rendern der Komponente ausgeführt wird.componentDidMount
nicht darüber gesprochencomponentWillMount
. Ich habe das in der Frage verpasst, mein schlechtes.Sie können den useMemo-Hook hacken, um ein componentWillMount-Lebenszyklusereignis zu imitieren. Mach einfach:
Sie müssten den useMemo-Hook vor allem behalten, was mit Ihrem Status interagiert. Dies ist nicht beabsichtigt, aber es hat bei allen ComponentWillMount-Problemen funktioniert.
Dies funktioniert, weil useMemo keinen Wert zurückgeben muss und Sie ihn nicht als irgendetwas verwenden müssen, sondern weil es einen Wert speichert, der auf Abhängigkeiten basiert, die nur einmal ausgeführt werden ("[]") und über unserer Komponente liegt Wird einmal ausgeführt, wenn die Komponente vor allem anderen bereitgestellt wird.
quelle
https://reactjs.org/docs/hooks-reference.html#usememo
quelle
Die Antwort von Ben Carp scheint mir nur eine gültige zu sein.
Da wir jedoch funktionale Methoden verwenden, kann nur ein anderer Ansatz von Closure und HoC profitieren:
Dann benutze es:
quelle
Kurze Antwort auf Ihre ursprüngliche Frage, wie
componentWillMount
mit React Hooks verwendet werden kann:componentWillMount
ist veraltet und gilt als Vermächtnis . Reagieren Empfehlung :In den Hook-FAQ erfahren Sie nun, was das Äquivalent eines Klassenkonstruktors für Funktionskomponenten ist:
Ein Anwendungsbeispiel
componentWillMount
sieht also so aus:quelle
Fügen Sie einfach ein leeres Abhängigkeitsarray in useEffect hinzu, als das es funktioniert
componentDidMount
.quelle
Es gibt einen einfachen Trick, um das zu simulieren
componentDidMount
und Folgendes zucomponentWillUnmount
verwendenuseEffect
:quelle