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

Detaillierte Erklärung von JavaScript zur Überwachung von Routenänderungen

Inhaltsverzeichnis Geschichte pushState() Methode...

Einige Erfahrung im Aufbau des React Native-Projektframeworks

React Native ist ein plattformübergreifendes Fram...

Zusammenfassung der Unterschiede zwischen SQL und NoSQL

Hauptunterschiede: 1. Typ SQL-Datenbanken werden ...

So ändern Sie die Server-UUID in MySQL

Quelle des Problems: Wenn der Slave-Server der ge...

Zusammenfassung häufig verwendeter Befehle für Linux-Dateioperationen

0. Neuer Betrieb: mkdir abc #Erstelle einen neuen...

MySQL 8.0.21 Installationsschritte und Problemlösungen

Laden Sie die offizielle Website herunter Gehen S...

Die Vue-Konfigurationsdatei generiert automatisch Routing- und Menüinstanzcode

Inhaltsverzeichnis Vorne geschrieben router.json ...

jQuery-Plugin zur Implementierung des Suchverlaufs

Jeden Tag ein jQuery-Plugin – um einen Suchverlau...

Detaillierte Erklärung zur Verwendung von Vue.prototype in Vue

Inhaltsverzeichnis 1. Einfaches Beispiel 2. Legen...

Docker startet im Status „Beendet“

Nach dem Docker-Lauf ist der Status immer „Beende...

Syntax-Alias-Problem basierend auf Löschen in MySQL

Inhaltsverzeichnis MySQL-Löschsyntax-Aliasproblem...