3 Punkte von GN⁺ 2024-08-17 | 1 Kommentare | Auf WhatsApp teilen

Beispiele für Vanilla JSX

Was wäre, wenn JSX DOM-Elemente zurückgibt?

  • Die Funktion ClickMe erstellt einen Button und zeigt die Anzahl der Klicks an
  • Bei jedem Klick auf den Button wird der Text aktualisiert
export default function ClickMe() {
  let i = 0;
  const el = <button>Click me</button> as HTMLButtonElement;
  el.onclick = (e) => {
    el.textContent = `Clicked ${++i} times`;
  };
  return el;
}

Wiederverwendbarkeit

  • Die Komponente ClickMe kann mehrfach verwendet werden, wobei jeweils ein eigener Zustand erhalten bleibt
import ClickMe from "./sample1.js";
export default () => <>
  <p><ClickMe /></p>
  <p><ClickMe /></p>
  <p><ClickMe /></p>
</>;

Erstellen eines interaktiven DOM-Baums

  • Mit den Klassen TodoInput und TodoList lässt sich eine To-do-Liste verwalten
  • Einträge können hinzugefügt und per Klick wieder entfernt werden
function TodoInput(attrs: { add: (v: string) => void }) {
  const input = <input /> as HTMLInputElement;
  input.placeholder = 'Add todo item...';
  input.onkeydown = (e) => {
    if (e.key === 'Enter') {
      attrs.add(input.value);
      input.value = '';
    }
  };
  return input;
}

class TodoList {
  ul = <ul class='todolist' /> as HTMLUListElement;
  add(v: string) {
    const item = <li>{v}</li> as HTMLLIElement;
    item.onclick = () => item.remove();
    this.ul.append(item);
  }
}

export default () => {
  const list = new TodoList();
  list.add('foo');
  list.add('bar');
  return <>
    <TodoInput add={(v) => list.add(v)} />
    {list.ul}
  </>;
};

Verarbeitung großer Datenmengen

  • Die Funktion FindNames verarbeitet große Datenmengen, filtert sie und zeigt die Ergebnisse an
  • Je nach Eingabewert werden passende Einträge in Echtzeit aktualisiert
import { data } from "../fetch-dataset.js";
export default function FindNames() {
  const status = <p style='margin:1em 0' /> as HTMLParagraphElement;
  const results = <ul /> as HTMLUListElement;
  const input = <input value='eri(c|k)a?' autocomplete='new-password' oninput={updateMatches} /> as HTMLInputElement;
  updateMatches();

  function updateMatches() {
    const matched = (data.entries().filter(([k]) => k.match(input.value)).toArray());
    const matches = (Iterator.from(matched).map(match => <Item regex={input.value} match={match} />).take(30));
    results.replaceChildren(...matches);
    status.textContent = `${matched.length} / ${data.size}`;
  }

  return <div class='sample4'>
    {input}
    {status}
    {results}
  </div>;
}

function Item(attrs: { match: [string, number], regex: string }) {
  const [name, count] = attrs.match;
  const total = <small style='color:#fff3'>({count})</small>;
  return <li>
    <span innerHTML={highlight(name, attrs.regex)} /> {total}
  </li>;
}

function highlight(str: string, regex: string) {
  if (!regex) return str;
  const r = new RegExp(`(${regex})`, 'gi');
  return str.replace(r, '<span class="match">$1</span>');
}

Einführung in imlib

  • imlib ist eine Bibliothek, die für immaculatalibrary.com entwickelt wurde
  • Sie wird zum Aufbau von minigamemaker.com und der Website verwendet, die Sie gerade lesen
  • Sie wurde entwickelt, weil bestehende Ansätze für Zustand nicht ausreichten, und ist die bevorzugte Methode zum Erstellen von Apps

GN⁺-Zusammenfassung

  • Dieser Artikel erklärt, wie sich mit JSX DOM-Elemente direkt erzeugen und interaktiv nutzen lassen
  • Er zeigt, wie sich auch ohne klassisches Virtual DOM große Datenmengen effizient verarbeiten lassen
  • Die Bibliothek imlib ermöglicht eine einfache und intuitive App-Entwicklung
  • Andere Projekte mit ähnlicher Funktionalität sind unter anderem React und Vue.js

1 Kommentare

 
GN⁺ 2024-08-17
Hacker-News-Kommentare
  • Danke für das Interesse am Projekt

    • Ich habe das Projekt gestartet, weil ich mit dem Zustand der SSGs in den letzten 10 Jahren unzufrieden war
    • Ich baue hauptsächlich statische Websites und wollte etwas Einfaches und Intuitives
    • JSX schien passend, aber ich war die Komplexität von JSX-Frameworks wie React leid
    • Ich habe ein SSG gebaut, das JSX als String rendert, und es dann erweitert, damit es im Browser als DOM-Elemente gerendert wird
    • In manchen Layouts funktioniert es gut mit gemeinsam genutzten Komponenten
    • Es funktioniert auch gut für SEO
    • Die IDE-Unterstützung ist nicht perfekt
  • Wenn echte DOM-Knoten zurückgegeben werden, geht ein großer Vorteil von JSX verloren

    • Man muss eine Beschreibung des DOM zurückgeben, damit Templates bei neuem Zustand erneut ausgewertet und effizient aktualisiert werden können
    • Das Beispiel aktualisiert mit der imperativen DOM-API
    • Ein wesentlicher Vorteil des VDOM ist das Iterieren über Elemente in Templates
    • Das Problem des VDOM ist langsames Diffing
  • Der Ursprung von JSX liegt in Facebooks XHP

    • XHP wurde von E4X inspiriert
  • Das letzte Beispiel funktioniert in Firefox nicht

    • In Edge funktioniert es, aber in Firefox tritt ein Fehler auf
  • Es ist Vanilla TSX sehr ähnlich

    • Es gibt ein App-Beispiel, das mit Vanilla TSX geschrieben wurde
  • Es erinnert an ActionScript 3

    • XML war ein Kernbestandteil der Sprache, und das hat Spaß gemacht, aber es wurde kein ES4
    • Es hat mehr als 10 Jahre gedauert, mit TypeScript und JSX ein ähnliches Niveau zu erreichen
  • Die Beispiele zeigen keine Komponenten mit Props, die sich im Laufe der Zeit ändern können

    • Es scheint schwierig zu sein, das auf komplexere Apps zu erweitern
  • Ich habe auch eine UI-Bibliothek auf Basis von JSX-Template-Ausdrücken gebaut, die echte DOM-Knoten erzeugen

    • Ich binde Modellobjekte an Eigenschaften, um Boilerplate für imperative Event-Handler zu vermeiden
    • Ich halte das für eine gute Idee
  • Ich verstehe den Reiz von JSX nicht

    • Andere Ansätze, die Schleifen, Variableneinfügung usw. automatisch bereitstellen, sind einfacher
  • Imba wird empfohlen

    • Es scheint nicht populär zu sein, weil JS-Entwickler leicht auf FAANG-Marketing hereinfallen