In dieser Serie wird ein kleines Frontend-Framework erstellt, das funktional React ähnelt, um zu veranschaulichen, wie React unter der Haube funktioniert. Dieses Kapitel behandelt JSX.
Ich werde Bun als Laufzeit verwenden. Der Knoten benötigt möglicherweise eine zusätzliche Konfiguration für Typoskript und Kompilierung.
Dieses Tutorial basiert auf diesem Tutorial, jedoch mit JSX, Typoskript und einem einfacheren Implementierungsansatz. Sie können sich die Notizen und den Code in meinem GitHub-Repo ansehen.
Bevor wir tiefer gehen, schauen wir uns zunächst einige wichtige Elemente von React-JSX an.
Wenn Sie sich jemals den transpilierten Code einer React-Komponente angesehen haben, werden Sie feststellen, dass es sich lediglich um eine Reihe von Funktionsaufrufen handelt. JSX ist nur ein syntaktischer Zucker für React.createElement. Das ist zum Beispiel der folgende JSX-Code:
const element = <h1 className="greeting">Hello, world!</h1>;
Wird transpiliert in:
const element = React.createElement( 'h1', {className: 'greeting'}, 'Hello, world!' );
React.createElement erstellt ein virtuelles Element, was ein weiterer Kernmechanismus ist. Vereinfacht ausgedrückt ist ein virtuelles Element das Element im virtuellen DOM. Ein virtuelles DOM ist etwas, das das tatsächliche DOM darstellt. Da es sich bei der Arbeit am virtuellen DOM lediglich um die Bedienung von js-Objekten handelt, ist sie viel schneller als die Arbeit am tatsächlichen DOM. Wir werden im nächsten Kapitel über virtuelles DOM sprechen. Aber im Moment reicht es aus zu wissen, dass JSX nur ein Syntaxzucker für React.createElement ist.
Die React.createElement-Funktion akzeptiert die folgenden Argumente der Reihe nach:
Es klingt nach einer einfachen Aufgabe, oder? Also lass es uns tun.
Wenn es um die Kompilierung geht, können wir die zu verwendende Funktion angeben – standardmäßig ist die Funktion React.createElement. Aber wir können unsere eigene Funktion verwenden.
Also erstellen wir ein v-dom.ts, um zuerst das virtuelle Element zu definieren.
export type VDomAttributes = { key?: string | number [_: string]: string | number | boolean | Function | undefined } export interface VDomElement { kind: 'element' tag: string children?: VDomNode[] props?: VDomAttributes key: string | number | undefined } export type VDomNode = | string | VDomElement
Bitte beachten Sie, dass wir in jedem Knoten ein Schlüsselfeld haben (Knoten ist nur ein Name für Text oder Element). Dies dient der Versöhnung, worüber wir im nächsten Kapitel sprechen werden. Sie können es vorerst getrost ignorieren.
Jetzt können wir die Funktion createElement implementieren. Wir legen es in derselben Datei ab.
export function createElement(tag: string, props: VDomAttributes, ...children: VDomNode[]): VDomElement { console.log('createElement', tag, props, children) return { kind: 'element', tag, children, props, key: props?.key ?? undefined } }
Jetzt weisen wir unseren Compiler an, diese Funktion zu verwenden. Wir können dies tun, indem wir die folgende Zeile am Anfang unserer Datei hinzufügen.
const element = <h1 className="greeting">Hello, world!</h1>;
Bitte beachten Sie, dass wir die React-Typdefinition einführen müssen, da wir den React-Standard übernehmen. Wir können dies tun, indem wir die folgende Zeile am Anfang unserer Datei hinzufügen.
const element = React.createElement( 'h1', {className: 'greeting'}, 'Hello, world!' );
Dann fügen wir in der tsconfig.json die folgende Zeile zum Feld „compilerOptions“ hinzu.
export type VDomAttributes = { key?: string | number [_: string]: string | number | boolean | Function | undefined } export interface VDomElement { kind: 'element' tag: string children?: VDomNode[] props?: VDomAttributes key: string | number | undefined } export type VDomNode = | string | VDomElement
Jetzt können wir einen Blick auf das virtuelle Element werfen, das wir erstellt haben.
export function createElement(tag: string, props: VDomAttributes, ...children: VDomNode[]): VDomElement { console.log('createElement', tag, props, children) return { kind: 'element', tag, children, props, key: props?.key ?? undefined } }
Sie sehen nur unser definiertes virtuelles Dom-Element basierend auf dem JSX-Code.
Darüber hinaus können wir auch ein Fragmentelement definieren – das <>>, wenn Sie seinen offiziellen Namen nicht kennen. Wir können dies tun, indem wir die folgende Zeile am Anfang unserer Datei hinzufügen.
Beim Umgang mit Fragmenten übernimmt der Compiler die konfigurierte Fragment-Factory zum Tag in der Elementerstellungsfunktion. Dies ist dasselbe wie die Funktionsweise von Funktionskomponenten – die Funktionskomponente übernimmt die Funktion zum Tag, was wir im nächsten Kapitel demonstrieren werden.
Trotzdem ist in unserer Implementierung keine komplexe Handhabung erforderlich – wir müssen lediglich ein spezielles Tag für das Fragment festlegen.
import { createElement as h } from './v-dom'
Zusätzliche Compiler-Optionen,
bun i @types/react
Im Grunde ist Fragment nur ein spezielles Element mit einem leeren Tag. Wenn es um die Erstellung eines Fragments geht, ruft der Compiler die jsxFragmentFactory ab und fügt sie in den Tag-Parameter im ersten Parameter von createElement ein. So können wir Fragmente leicht von anderen Elementen unterscheiden.
"compilerOptions": { "jsx": "react", "jsxFactory": "createElement", }
Dieser Code wird das virtuelle DOM korrigieren. Bisher haben wir den JSX-Teil unseres Tiny React implementiert.
Ugh, das ist der Autor aus Kapitel drei. Tatsächlich ist die aktuelle Implementierung von JSX nicht perfekt. Wir werden es im dritten Kapitel beheben. Jetzt unterstützt es keine Syntax wie
import { createElement } from "./v-dom"; function App() { return <div> <h1>a</h1> <h2>b</h2> </div> } console.log(App());
Das liegt daran, dass jedes {} als ein untergeordnetes Element behandelt wird, während die Karte ein Array zurückgibt. Es wird also verschachtelte Kinder haben.
Außerdem hatten wir noch keine Funktionskomponenten unterstützt, was im nächsten Kapitel steht.
Sie können einfach dem aktuellen folgen und es später korrigieren. Entschuldigen Sie die Unannehmlichkeiten.
Das obige ist der detaillierte Inhalt vonBauen Sie einen Tiny React ChSX. Für weitere Informationen folgen Sie bitte anderen verwandten Artikeln auf der PHP chinesischen Website!