Heim  >  Artikel  >  Web-Frontend  >  Bauen Sie einen Tiny React ChSX

Bauen Sie einen Tiny React ChSX

Mary-Kate Olsen
Mary-Kate OlsenOriginal
2024-10-20 18:29:30216Durchsuche

Build a Tiny React ChSX

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.

JSX

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:

  1. Der Tag-Name des Elements. Einige Tags sind speziell, wie div, span, h1 usw. Diese werden als intrinsische Elemente bezeichnet. Einige Tags sind benutzerdefinierte Komponenten.
  2. Die Requisiten des Elements. Dies ist ein Objekt, das die Eigenschaften des Elements enthält. Der Klassenname des obigen h1-Elements lautet beispielsweise Greeting.
  3. Die Kinder des Elements. Dies kann eine Zeichenfolge oder ein Element sein. Bitte beachten Sie, dass dieser Parameter in der Funktionssignatur als ...untergeordnete Elemente dargestellt wird, was bedeutet, dass er eine beliebige Anzahl von Argumenten annehmen kann.

Es klingt nach einer einfachen Aufgabe, oder? Also lass es uns tun.

Implementieren Sie JSX

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.

Fußnote

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!

Stellungnahme:
Der Inhalt dieses Artikels wird freiwillig von Internetnutzern beigesteuert und das Urheberrecht liegt beim ursprünglichen Autor. Diese Website übernimmt keine entsprechende rechtliche Verantwortung. Wenn Sie Inhalte finden, bei denen der Verdacht eines Plagiats oder einer Rechtsverletzung besteht, wenden Sie sich bitte an admin@php.cn