Die Hooks von React sind eine Funktion, die nach der Glasfaser aufgetaucht ist. Daher glauben viele Menschen fälschlicherweise, dass die Implementierung von Hooks auf Glasfasern basieren muss. Dies ist jedoch nicht unbedingt der Fall.
Jetzt werden Hooks nicht nur in React implementiert, sondern auch in Frameworks wie Preact, React SSR und Midway. Ihre Implementierung ist nicht auf Fiber angewiesen.
Werfen wir einen Blick darauf, wie Hooks in diesen verschiedenen Frameworks implementiert werden:
React beschreibt die Schnittstelle über jsx, die von Kompilierungstools wie babel oder tsc in eine Renderfunktion kompiliert und dann ausgeführt wird, um vdom zu generieren:
Die Renderfunktion war hier React.createElement vor React17:
Nach React 17 wurde es in jsx geändert:
Diese jsx-Runtime wird automatisch eingeführt, und es ist nicht wie bisher erforderlich, einen React-Import für jede Komponente beizubehalten.
Die Ausführung der Renderfunktion generiert vdom:
Die Struktur von vdom ist wie folgt:
Vor React16 wurde dieser VDOM rekursiv gerendert, wobei der echte Dom hinzugefügt, gelöscht und geändert wurde.
Nachdem React16 die Fiber-Architektur eingeführt hatte, gab es einen zusätzlichen Schritt: Zuerst wurde vdom in Fiber konvertiert und dann die Fiber gerendert.
Der Prozess der Konvertierung von VDOM in Fiber wird als Reconcile bezeichnet, und der abschließende Prozess des Hinzufügens, Löschens und Änderns des echten Doms wird als Commit bezeichnet.
Warum müssen wir eine solche Umstellung vornehmen?
Da vdom nur Verweise auf die untergeordneten Knoten des untergeordneten Knotens und keine Verweise auf den übergeordneten Knoten des übergeordneten Knotens und andere Geschwisterknoten enthält, führt dies dazu, dass alle vdom-Knoten gleichzeitig und ohne Unterbrechung rekursiv in den dom gerendert werden müssen.
Was passiert, wenn es unterbrochen wird? Da der übergeordnete Knoten und die Geschwisterknoten nicht aufgezeichnet werden, können wir nur die untergeordneten Knoten weiter verarbeiten, andere Teile des VDOM jedoch nicht.
Aus diesem Grund hat React diese Art von Faserstruktur eingeführt, die Referenzen wie die Rückkehr des übergeordneten Knotens, die untergeordneten Knoten des untergeordneten Knotens, die Geschwister des Geschwisterknotens usw. enthält, die unterbrochen werden können, da alle unverarbeiteten Knoten nach der Unterbrechung und Wiederherstellung gefunden werden können.
Die Struktur des Faserknotens ist wie folgt:
Dieser Prozess kann unterbrochen werden und natürlich kann er geplant werden, was ein Zeitplanprozess ist.
Daher ist die Glasfaserarchitektur in drei Phasen unterteilt: Planen, Abgleichen (VDOM in Glasfaser konvertieren) und Festschreiben (Auf Dom aktualisieren).
In Funktionskomponenten können Hooks verwendet werden, um auf einige Werte zuzugreifen. Diese Werte werden auf dem Faserknoten gespeichert.
In dieser Funktionskomponente werden beispielsweise 6 Hooks verwendet:
Dann gibt es eine memorizedState-verknüpfte Liste mit 6 Elementen auf dem entsprechenden Faserknoten:
Verkettet mit „next“:
Verschiedene Hooks greifen auf Werte für verschiedene Elemente der verknüpften Liste memorizedState zu. Dies ist das Prinzip von React-Hooks.
Diese verknüpfte Liste verfügt über eine Erstellungsphase und eine Aktualisierungsphase. Sie werden also feststellen, dass die endgültige Implementierung von useXxx in mountXxx und updateXxx unterteilt ist:
Die Mount-Phase besteht hier darin, Hook-Knoten zu erstellen und sie zu einer verknüpften Liste zusammenzustellen:
Die erstellte Hook-verknüpfte Liste wird mit dem memorizedState-Attribut des Fiber-Knotens verknüpft.
Beim Aktualisieren können Sie diese Hook-Liste natürlich vom Fiber-Knoten abrufen:
Auf diese Weise kann die useXxx-API in mehreren Renderings den entsprechenden memorizedState auf dem Fiber-Knoten finden.
Dies ist das Prinzip von React Hooks. Sie können sehen, dass der Hook auf dem Faserknoten gespeichert wird.
Was ist also der Unterschied zu preact?
Preact ist ein schlankeres Framework, das mit React-Code kompatibel ist. Es unterstützt Klassenkomponenten und Funktionskomponenten sowie React-Funktionen wie Hooks. Es implementiert jedoch nicht die Glasfaserarchitektur.
Denn es berücksichtigt hauptsächlich die ultimative Größe (nur 3 KB) und nicht die ultimative Leistung.
Wir haben gerade erfahren, dass React die Hook-Liste auf dem Fiber-Knoten speichert. Wenn Preact keinen Fiber-Knoten hat, wo wird die Hook-Liste gespeichert?
Tatsächlich ist es leicht zu glauben, dass Glasfaser nur vdom ändert, um die Leistung zu verbessern, und dass es keinen wesentlichen Unterschied zu vdom gibt. Können wir den Hook dann einfach auf vdom speichern?
Tatsächlich platziert Preact die Hook-Liste auf vdom.
Diese Funktionskomponente hat beispielsweise 4 Hooks:
Seine Implementierung besteht darin, auf den entsprechenden Hook auf vdom zuzugreifen:
Es unterteilt den Hook nicht wie React in zwei Phasen, Mount und Update, sondern führt sie zur Verarbeitung zusammen.
Wie in der Abbildung gezeigt, werden Hooks im Array „component.__hooks“ gespeichert und über Indizes auf sie zugegriffen.
Diese Komponente ist ein Attribut auf vdom:
Das heißt, der Wert von Hooks wird im Array vnode._component._hooks gespeichert.
Vergleichen Sie die Unterschiede zwischen React und Preact bei der Implementierung von Hooks:
In React wird die Hook-Liste im Attribut „fibreNode.memorizedState“ gespeichert, in Preact wird die Hook-Liste im Attribut „vnode._component._hooks“ gespeichert.
Die Hook-Liste in React wird verkettet bis next und in preact Die Hook-verknüpfte Liste ist ein Array,
das die Erstellung und Aktualisierung der Hook-verknüpften Liste durch den Indexzugriff trennt
ist die Implementierung von Hooks nicht auf Glasfaser angewiesen, sondern muss nur einen Ort zum Speichern der Hook-Daten finden, die der Komponente entsprechen. Solange sie beim Rendern abgerufen werden können, spielt es keine Rolle, wo sie gespeichert sind.
Da vdom, Fiber und Component Rendering eng miteinander verbunden sind, werden sie in diesen Strukturen gespeichert.
Wenn beispielsweise „react ssr“ Hooks implementiert, existiert dieser weder auf Fiber noch auf vdom:
Tatsächlich kann das Paket „react-dom“ zusätzlich zu „csr“ auch „ssr“ ausführen:
Verwenden Sie die Render-Methode von „react- dom wenn csr:
Verwenden Sie bei ssr die renderToString-Methode oder die renderToStream-Methode von React-Dom/Server:
Glauben Sie, dass die Konvertierung von VDOM zu Glasfaser während der SSD erfolgen wird?
Definitiv nicht. Fiber ist eine Struktur, die eingeführt wurde, um die Rendering-Leistung bei der Ausführung im Browser zu verbessern, Berechnungen unterbrechbar zu machen und Berechnungen im Leerlauf durchzuführen.
Für das serverseitige Rendering ist natürlich keine Glasfaser erforderlich.
Wenn Fiber nicht benötigt wird, wo wird die Hook-Liste gespeichert? vdom?
Es kann zwar in vdom platziert werden, ist es aber nicht.
Verwenden Sie beispielsweise Ref-Hooks:
Es handelt sich um eine verknüpfte Liste, die mit „next“ verkettet ist, beginnend mit „firstWorkInProgressHook“.
Und firstWorkInProgressHook ist der erste Hook-Knoten, der mit createHook erstellt wurde:
Es ist nicht auf vdom gemountet.
Warum?
Da ssr nur einmal gerendert und nicht aktualisiert werden muss, muss es nicht an vdom hängen.
Löschen Sie einfach die Hook-Liste jedes Mal, wenn Sie mit der Verarbeitung der Hooks jeder Komponente fertig sind:
Daher sind bei der Verwendung von React SSR Hooks in globalen Variablen vorhanden.
Vergleichen Sie den Unterschied in den Implementierungsprinzipien von Hooks in React CSR und SSR:
In CSR wird Fiber aus VDOM erstellt, das verwendet wird, um das Rendern unterbrechbar zu machen und die Leistung durch Leerlaufplanung zu verbessern. In SSR wird es jedoch nicht direkt gerendert Bei Verwendung von
csr werden Hooks im Faserknoten gespeichert, während sie bei Verwendung von ssr direkt auf globalen Variablen platziert und nach der Verarbeitung jeder Komponente gelöscht werden. Da CSR nicht ein zweites Mal verwendet wird
, wird die Erstellung und Aktualisierung von Hooks in zwei Phasen unterteilt: Mounten und Aktualisieren, während SSR nur einmal verarbeitet wird und nur die Erstellungsphase erfolgt.
Das Implementierungsprinzip von Hooks ist eigentlich nicht kompliziert Das heißt, in einem bestimmten Kontext wird eine verknüpfte Liste in der verknüpften Liste gespeichert, und dann greift die Hook-API auf die entsprechenden Daten aus verschiedenen Elementen der verknüpften Liste zu, um ihre jeweilige Logik zu vervollständigen. Dieser Kontext kann vdom, Fiber oder sogar eine globale Variable sein.
Die Idee von Hooks ist jedoch immer noch sehr beliebt. Das von Taobao produzierte serverseitige Framework hat die Idee von Hooks eingeführt:
?
Das serverseitige Framework verfügt natürlich nicht über Strukturen wie vdom und fibre, aber die Idee von Hooks basiert nicht auf diesen. Um die Hooks-API zu implementieren, müssen Sie lediglich eine verknüpfte Liste in einem bestimmten Kontext platzieren.
Midway implementiert eine API ähnlich wie React Hooks:
Ich habe nicht genau nachgesehen, wo die Hook-Liste vorhanden ist, aber wir beherrschen bereits das Implementierungsprinzip von Hooks. Solange es einen Kontext zum Speichern der Hook-Liste gibt, kann sie überall sein.
React-Hooks eine Funktion sind, die nach der React-Fiber-Architektur entstanden ist. Viele Leute glauben fälschlicherweise, dass Hooks mit Fiber implementiert werden müssen. Wir haben uns die Implementierung von Hooks in React, Preact, React SSR und Midway angesehen und festgestellt Dies ist nicht der Fall:
gibt Müssen React Hooks also auf Glasfaser angewiesen sein, um es zu implementieren?
Offensichtlich nicht, es kann mit Fiber, VDOM, globalen Variablen oder sogar jedem beliebigen Kontext verwendet werden.