Wie React unter der Haube funktioniert

React ist eine sehr beliebte JavaScript-Bibliothek. Mit über 5,5 Millionen wöchentlichen Downloads erfreut sich React großer Beliebtheit. Aber nicht viele React-Entwickler wissen, wie React unter der Haube funktioniert.

In diesem Beitrag werde ich versuchen, einige interessante Dinge über React aufzudecken, die Sie als React-Entwickler vielleicht faszinieren. Beginnen wir am Anfang.

Aber bevor wir anfangen, wenn Sie ein React-Entwickler sind, habe ich einige aufregende Neuigkeiten für Sie! Sobald Sie diesen Artikel fertiggestellt haben, können Sie mit React etwas Cooles entwickeln und unterwegs Preise gewinnen :)

Was macht React?

Im Kern pflegt React im Grunde einen Baum für Sie. Dieser Baum kann effiziente Diff-Berechnungen auf den Knoten durchführen.

Stellen Sie sich Ihren HTML-Code als Baum vor. Genau so behandelt der Browser Ihr DOM (Ihr im Browser gerendertes HTML). Mit React können Sie Ihr DOM in JavaScript effektiv neu erstellen und nur die tatsächlich vorgenommenen Änderungen in das DOM übertragen.

JSX ist syntaktischer Zucker

Es gibt nichts Vergleichbares wie JSX - weder für JavaScript noch für den Browser. JSX ist einfach syntaktischer Zucker zum Erstellen sehr spezifischer JavaScript-Objekte.

Wenn Sie etwas schreiben wie:

const tag = 

Hello

Was Sie im Wesentlichen tun, ist Folgendes:

const tag = React.createElement("h1", {}, "Hello")

Sie sehen, wenn Sie anfangen, verschachtelte Inhalte zu schreiben, ist dies nicht nur schwierig zu codieren, sondern es wird auch sehr unpraktisch, eine solche Codebasis zu verwalten. JSX hilft Ihnen somit, die Sauberkeit von HTML in die Leistungsfähigkeit von JavaScript zu bringen.

Aber was macht React.createElement selbst? Es wird ein einfaches altes JavaScript-Objekt erstellt. In der Tat können Sie es manuell aufrufen und selbst sehen!

Sie sehen, wir haben ein Objekt wie dieses:

{ $$typeof: Symbol(react.element), key: null, props: {children: "Hello"}, ref: null, type: "div" }

Und wenn wir anfangen, Elemente wie diese zu verschachteln:

React.createElement('div', { }, React.createElement('p', {}, 'A p inside a div') ) 

Wir würden anfangen, verschachtelte Objekte zu bekommen:

Sobald alle JSX-Dateien analysiert und alle React.createElement-Aufrufe aufgelöst wurden, landen wir mit einem riesigen verschachtelten Objekt wie oben.

Renderer reagieren

Wenn Sie jetzt zu dem Punkt zurückkehren, an dem wir unsere App starten, sehen Sie in Ihrer Datei index.js die folgende Zeile:

// .. prev code ReactDOM.render(, container)

Von oben wissen wir, dass dies nach dem Parsen nur ein riesiges Objekt von React-Elementen ist. Wie kann React dann tatsächliche divs und p-Tags daraus erstellen? Treffen Sie ReactDOM.

ReactDOM erstellt wiederum rekursiv Knoten in Abhängigkeit von ihrer 'type'-Eigenschaft und hängt sie schließlich an das DOM an.

An dieser Stelle sollte klar sein, warum das Entkoppeln von React von den Renderern tatsächlich ein großartiger Schritt ist! React erstellt einfach einen Baum der Benutzeroberfläche, der nicht nur im Web, sondern auch in Umgebungen wie Mobilgeräten verwendet werden kann, sofern ein Renderer verfügbar ist, der mit dem Host-Betriebssystem kommunizieren kann. Hier kommt React Native zum Spielen. Sie sehen, React Native verwendet die React-Bibliothek, nicht jedoch ReactDOM als Rendering. Stattdessen ist das reaktionsnative Paket selbst ein Renderer.

Wir tun dies in einer reaktiven nativen Anwendung, um die App zu starten:

const { AppRegistry } = require('react-native') AppRegistry.registerComponent('app', () => MainComponent)

Aussehen! Kein ReactDOM. Warum nicht? Da wir keine Methoden wie appendChild haben, haben wir auch keine DOM-ähnliche Umgebung. Stattdessen benötigen wir für Handys Unterstützung für die Benutzeroberfläche direkt vom Betriebssystem. Aber die React-Bibliothek muss das nicht wissen, der Renderer (React Native) kümmert sich darum.

Versöhnung reagieren

Wenn wir sagen, dass React eine Kopie von DOM unter Verwendung von virtuellem DOM in JavaScript verwaltet und es verwendet, um es auf Änderungen zu differenzieren und es auf reales DOM anzuwenden, möchten wir nicht, dass React seinen Weg brutal erzwingt. Reagieren, in der Tat sehr faul Versöhnung. Reagieren würde die geringstmögliche Anzahl von Änderungen ermöglichen, dh es würde versuchen, Elemente, Attribute und sogar Stile nach Möglichkeit wiederzuverwenden!

Betrachten Sie dieses Beispiel:

stuff

Angenommen, Sie ändern diesen JSX-Ausdruck unter Verwendung einer Bedingung oder eines Status in den folgenden:

something else

Während React sich unterscheidet, würde das img-Tag den gleichen Klassennamen sowohl in alten als auch in neuen Bäumen verwenden. Warum also ändern? Und es würde einfach Ihr alt-Attribut ändern und weitermachen.

Es gibt jedoch einen Haken. Da wir nicht möchten, dass React viele Berechnungen für unterschiedliche Teile durchführt, würde React davon ausgehen, dass sich der enthaltende Teilbaum eines übergeordneten Elements definitiv geändert hat, wenn sich ein Elternteil geändert hat. Zum Beispiel:

I did not change

Wenn Sie diese JSX mit Bedingung / Status wie folgt ändern:

I did not change

Sie konnten zwar sehen, dass wir das innere p-Tag nicht neu erstellen müssen, aber React kann dies nicht wissen, während Sie den Baum von oben durchqueren (es sei denn, Sie führen natürlich eine starke Baumdifferenzierung durch, die viel teurere Algorithmen sind als Die heuristische O (n) -Reaktion folgt zur Differenzierung. Daher beschließt React, alle untergeordneten Elemente zu zerstören (dh ihre Bereinigungsfunktionen in useEffect oder componentWillUnmount in klassenbasierten Komponenten aufzurufen) und die untergeordneten Elemente von Grund auf neu zu erstellen.

Reaktionstasten

Beim Hinzufügen / Entfernen von Elementen in einem Knoten würde React einfach die untergeordneten Elemente im alten Baum und die untergeordneten Elemente im neuen Baum des Knotens durchlaufen und die Stellen markieren, an denen das Hinzufügen / Entfernen durchgeführt werden muss. Dies hat jedoch einen Nachteil ohne zusätzliche Hilfe des Entwicklers. Betrachten Sie dieses Beispiel:

  • A
  • B

Beachten Sie, dass dies je nach Bedingung / Status wie folgt geändert wird:

  • Z
  • A
  • B

Wenn React nun anfängt, die beiden Listen auf Unterschiede zu vergleichen, findet es den Unterschied am untergeordneten Knoten 1, mutiert das alte A zu neuem Z und mutiert es erneut am untergeordneten Knoten 2 vom alten B zu neuem A, und dann schließlich den neuen B-Knoten anhängen.

Ein besserer Weg wäre jedoch gewesen, die vorhandenen A- und B-Knoten beizubehalten und nur den Z-Knoten voranzustellen. Aber wie würde React davon erfahren? Reaktionstasten würden helfen.

Tasten bieten nur eine gute Möglichkeit, um zu reagieren, um zu wissen, welche Elemente sich während des Unterschieds geändert haben oder nicht. Anstatt das gesamte Element zu vergleichen, vergleicht React nun die Schlüssel der untergeordneten Elemente, um festzustellen, welches Element hinzugefügt / entfernt werden muss. Der folgende Weg ist ein effizienter Weg, um dasselbe auszuführen:

  • A
  • B

Wenn dies nun geändert wird zu:

  • Z
  • A
  • B

React würde jetzt wissen, dass die Schlüssel 'A' und 'B' bereits vorhanden sind, sodass wir nur das neue Element mit dem Schlüssel 'Z' hinzufügen müssen.

Sind Sie ein React-Entwickler? Zeigen Sie Ihre React-Fähigkeiten, indem Sie in React ein 3-minütiges interaktives Spiel entwickeln und Hoodies, Shirts und Kaffeetassen gewinnen ! Nehmen Sie teil an codecomp von codedamn der Zwietracht Server verbinden hier

Dies waren also einige wichtige Konzepte, von denen ich glaube, dass sie für Sie als React-Entwickler sehr hilfreich sind, um den Kern von React und dessen Funktionsweise zu verstehen. Sie können gerne Vorschläge oder Fragen weitergeben, die Sie dazu haben.

Sie können mir auf Twitter folgen, um weitere JS / Coding-Tweets und andere Dinge zu erhalten. Frieden!