Der Unterschied zwischen useEffect und useLayoutEffect in React

Der Unterschied zwischen useEffect und useLayoutEffect in React

Voraussetzungen

Wir können den Workflow von React in mehrere Teile unterteilen:

  1. Rendering-Phase: Generiert hauptsächlich Fiber-Knoten und erstellt einen vollständigen Fiber-Baum
  2. Commit-Phase: In der vorherigen Renderphase wird eine Nebeneffektliste auf der Root-Fiber generiert, und in dieser Phase werden die DOM-Operationen der Anwendung ausgeführt

Die Arbeit in der Commit-Phase gliedert sich hauptsächlich in drei Teile und die entsprechenden Funktionsnamen im Quellcode lauten:

  • commitBeforeMutationEffects-Phase: behandelt hauptsächlich einige verwandte Operationen, bevor DOM-Operationen ausgeführt werden
  • commitMutationEffects-Phase: Ausführen von DOM-Operationen
  • commitLayoutEffects-Phase: behandelt hauptsächlich einige verwandte Vorgänge nach der Durchführung von DOM-Vorgängen

Der Unterschied zwischen useEffect und useLayoutEffect liegt hauptsächlich in der Verarbeitung dieser drei Phasen. Die Schlussfolgerung lautet: useEffect führt seine Antwortfunktion und die letzte Zerstörungsfunktion asynchron aus, während useLayoutEffect seine Antwortfunktion und die letzte Zerstörungsfunktion synchron ausführt, wodurch das DOM-Rendering blockiert wird.

Effekt verwenden

commitBeforeMutationEffects

In dieser Phase konzentriert sich useEffect auf den folgenden Satz:

Funktion commitBeforeMutationEffects() {
  während (nächsterEffekt$1 !== null) {
    // Eine Reihe von Zuweisungsoperationen werden ausgelassen. Die Flags hier sollten aus den Flags des Effekts der entsprechenden FunctionComponent übernommen werden. Für eine spezifische Implementierung verweisen wir auf den Quellcode var flags = effect.flags;

  // Lebenszyklus wird verarbeitet, wenn ((Flags & Snapshot) !== NoFlags) {
      setCurrentFiber(nächsterEffekt$1);
      commitBeforeMutationLifeCycles(aktueller, nächsterEffekt$1);
      ResetCurrentFiber();
    }

 // Diese if-Anweisung prüft nur, ob useEffect wahr und useLayoutEffect falsch ist.
    if ((flags & Passive) !== NoFlags) {
      // Wenn passive Effekte vorhanden sind, planen Sie einen Rückruf zum Leeren bei
      // die frühestmögliche Gelegenheit.
      wenn (!rootDoesHavePassiveEffects) {
        rootDoesHavePassiveEffects = wahr;
 // Aus diesem Grund ist useEffect asynchron. React plant flushPassiveEffects nach dem DOM-Vorgang.
        scheduleCallback(NormalePriorität, Funktion () {
          füge PassiveEffects hinzu
          gibt null zurück;
        });
      }
    }

    nächsterEffekt$1 = nächsterEffekt$1.nächsterEffekt;
  }
}

commitMutationEffects

Während dieser Phase führt React eine Reihe von DOM-Knotenaktualisierungen durch und führt dann eine Methode aus: commitHookEffectListUnmount(HookLayout | HookHasEffect, finishedWork);

Dann entspricht eine Funktionskomponente mit useEffect in dieser Phase nicht der Beurteilungslogik zum Aushängen, sodass der Aushängevorgang an dieser Stelle nicht ausgeführt wird.

commitLayoutEffects

In dieser Phase gibt es noch eine sehr wichtige Methode: commitHookEffectListMount(HookLayout | HookHasEffect, finishedWork);

Diese if-Beurteilung ist dieselbe wie die if-Beurteilung im vorherigen Schritt. useEffec führt bei dieser Beurteilung keine Operation aus.

Nachfolgende Phasen

Nach Abschluss von commitLayoutEffects gibt es noch eine weitere Operation:

wenn (rootDoesHavePassiveEffects) {
    // Dieses Commit hat passive Effekte. Verwahre einen Verweis darauf. Aber nicht
    // Planen Sie einen Rückruf, bis die Layoutarbeit abgeschlossen ist.
    rootDoesHavePassiveEffects = falsch;
    rootWithPendingPassiveEffects = Wurzel;
    pendingPassiveEffectsLanes = Fahrspuren;
    pendingPassiveEffectsRenderPriority = Render-Prioritätsstufe;
  }

Das heißt, rootWithPendingPassiveEffects wird auf root gesetzt. Der Grund dafür hängt mit der nächsten asynchronen Planung von flushPassiveEffects zusammen, die von useEffect in der ersten Phase commitBeforeMutationEffects registriert wurde. Sehen wir uns die folgende Implementierung von flushPassiveEffects an:

Funktion flushPassiveEffectsImpl() {
 wenn (rootWithPendingPassiveEffects === null) {
    gibt false zurück;
  }
 //Eine Reihe von Leistungsverfolgungsvorgängen auslassen commitPassiveUnmountEffects(root.current);
  commitPassiveMountEffects(root, root.current);
}


Wie aus dem obigen Codeausschnitt ersichtlich ist, wird der in der ersten Phase von useEffect registrierte Planungsrückruf nach der Aktualisierung der Seite ausgehängt und wieder eingehängt. Es ist erwähnenswert, dass der Effekt in diesem Rückruf in der Phase „commitLayoutEffects“ registriert wird.

useLayoutEffect

Tatsächlich wird useLayoutEffect gemäß unserer Analyse von useEffect in den if-Beurteilungen in den Phasen commitMutationEffects und commitLayoutEffects durch if beurteilt, sodass in der Phase commitMutationEffects die letzte Zerstörungsfunktion von useLayoutEffect synchron ausgeführt wird und in der Phase commitLayoutEffects die Ausführungsfunktion von useLayoutEffect dieses Mal synchron ausgeführt und die Zerstörungsfunktion registriert wird.

abschließend

Bisher haben wir den Code der Commit-Phase grob überprüft und analysiert, warum useEffect asynchron und useLayoutEffect synchron ausgeführt wird. Ich habe im Artikel nicht zu viel spezifischen Code gepostet, da diese alle variabel sind. Die tatsächliche Prozessübersicht und das mentale Modell des React-Teams, das diesen Mechanismus entwirft, erfordern, dass wir uns durch kontinuierliches Debuggen und Verstehen des Codes langsam damit vertraut machen.

Was mich später interessiert, ist die Implementierung von Hooks. Dabei werde ich mich auf den Quellcode des kritischeren useReducer konzentrieren, um zu sehen, ob ich eine einfache Version schreiben und sie in das Alipay-Applet einfügen kann, um benutzerdefinierte Alipay-Hooks für die tägliche Produktivitätsentwicklung zu implementieren.

Dies ist das Ende dieses Artikels über den Unterschied zwischen useEffect und useLayoutEffect in React. Weitere relevante Inhalte zu useEffect useLayoutEffect von React finden Sie in den vorherigen Artikeln von 123WORDPRESS.COM oder in den folgenden verwandten Artikeln. Ich hoffe, dass jeder 123WORDPRESS.COM in Zukunft unterstützen wird!

Das könnte Sie auch interessieren:
  • Eine kurze Diskussion über die Fallstricke der React UseEffect-Abschließung
  • React useEffect verstehen und verwenden

<<:  Tutorial zum Bereitstellen des Open-Source-Projekts Tcloud mit Docker auf CentOS8

>>:  Lösen Sie die Probleme, die bei der Installation der Mysql 8.0.17 Winx64-Version aufgetreten sind

Artikel empfehlen

Eine gängige Technik zur Implementierung von Dreiecken mit CSS (mehrere Methoden)

In manchen Vorstellungsgesprächen werden häufig F...

Webentwickler sind besorgt über die Koexistenz von IE7 und IE8

Ich habe heute IE8 installiert. Als ich auf die M...

Details zu 7 Arten der Komponentenkommunikation in Vue3

Inhaltsverzeichnis 1. Kommunikationsmethode für V...

Detaillierte Erklärung der Anwendungsfälle von Vue-Listenern

Die erste Möglichkeit besteht darin, jQuery's...

Neue Funktionen in MySQL 8.0: Hash Join

Das MySQL-Entwicklungsteam hat am 14. Oktober 201...

So kompilieren Sie den Linux-Kernel

1. Laden Sie die erforderliche Kernel-Version her...

Kleines Problem mit dem Abstand zwischen Label und Eingabe im Google Browser

Erst Code, dann Text Code kopieren Der Code lautet...

Das Prinzip und die Implementierung des JS-Drag-Effekts

Die Drag-Funktion wird hauptsächlich verwendet, u...

mysql 8.0.18 mgr-Installation und seine Umschaltfunktion

1. Systeminstallationspaket yum -y install make g...

Tutorial zur Oracle-Bereitstellung in einer Linux-Umgebung

1. Umgebung und zugehörige Software Virtuelle Mas...

Natives JS zum Erstellen eines verschiebbaren Anmeldefelds

Dieser Artikel zeigt ein verschiebbares Anmeldefe...

Objektorientierte JavaScript-Implementierung eines Lupengehäuses

In diesem Artikel wird der spezifische Code der o...

So ermitteln Sie, ob das Linux-System auf VMware installiert ist

Wie kann festgestellt werden, ob das aktuelle Lin...