7.1 React-Grundlagen: React und das Vite-Projekt
Nach dieser Einheit kannst du:
- erklären, was React ist, und es von Frameworks wie Angular abgrenzen.
- das deklarative Modell (“die Oberfläche ist eine Funktion des Zustands”) gegen direkte DOM-Manipulation abgrenzen.
- die Rolle des Virtual DOM beim Aktualisieren der Seite beschreiben.
- ein React-Projekt mit Vite und TypeScript anlegen, starten und für die Auslieferung bauen.
Am Bahnhof hängt eine Anzeigetafel. Es gibt zwei Arten, sie aktuell zu halten: Jemand klettert bei jeder Änderung hinauf und dreht die Buchstaben einzeln um, Zug für Zug, Zeile für Zeile, und wehe, eine Zeile wird vergessen. Oder: Jemand reicht den aktuellen Fahrplan hinauf, und die Tafel stellt sich selbst darauf ein. Die erste Methode ist direkte DOM-Manipulation, die zweite ist React.
flowchart LR
accTitle: Zwei Arten, eine Anzeigetafel aktuell zu halten
subgraph imp["imperativ: Schritte"]
direction TB
i1["Zug verspätet"] --> i2["Zeile 3 suchen"]
i2 --> i3["Uhrzeit umdrehen"]
i3 --> i4["Gleis umdrehen?<br/>vergessen!"]
end
subgraph dec["deklarativ: Ergebnis"]
direction TB
d1["neuer Fahrplan"] --> d2["Tafel stellt sich<br/>selbst ein"]
end
Abb. 7.1: Imperativ beschreibst du jeden Schritt, deklarativ nur das Ergebnis (eigene Darstellung).
React ist die Bibliothek, mit der in diesem Jahr Benutzeroberflächen entstehen. Ihr Kern ist genau dieser Denkwechsel: Statt die Oberfläche Schritt für Schritt zu verändern (“finde das Element, ändere seinen Text, hänge eine Klasse dazu”), beschreibst du, wie die Oberfläche für einen gegebenen Zustand auszusehen hat, und React kümmert sich um die Änderungen. Kurz: Die Oberfläche ist eine Funktion des Zustands.
Kapitel 7 hat sechs Einheiten. Diese erste klärt, was React ist, wie es die Seite aktualisiert und wie ein Projekt entsteht. Danach folgen JSX und Komponenten (7.2), Props, Listen und Events (7.3), State (7.4), Datenfluss und Formulare (7.5) und die Hook-Familie (7.6). Ab dem Abschnitt Das Projekt ist jede Codezeile TypeScript, jede Komponentendatei eine .tsx-Datei: Untypisierte Props wären genau die Fehlerquelle, gegen die Kapitel 1 angetreten ist.
Begriffe vorab
Abschnitt betitelt „Begriffe vorab“- DOM (Document Object Model): die Objektdarstellung einer HTML-Seite im Browser, ein Baum aus Elementen, Attributen und Texten.
- Bibliothek und Framework: Eine Bibliothek rufst du für eine Aufgabe auf; ein Framework gibt die Struktur der ganzen Anwendung vor.
- Single Page Application (SPA): Der Browser lädt die Seite einmal; danach tauscht JavaScript nur noch Inhalte aus.
- Komponente: ein wiederverwendbarer Oberflächenbaustein, in React eine Funktion, die Oberfläche zurückgibt.
- Vite: das Werkzeug, das ein React-Projekt anlegt, im Entwicklungsserver ausführt und für die Auslieferung baut.
Was React ist und was es nicht ist
Abschnitt betitelt „Was React ist und was es nicht ist“React ist eine Bibliothek, kein vollständiges Framework: Es kümmert sich um die Oberfläche und um sonst nichts. Routing, Datenzugriff, Formularvalidierung oder ein Build-Werkzeug bringt React nicht mit; das kommt aus dem Ökosystem und ab Kapitel 8 von Next.js. Entwickelt wurde React bei Facebook (heute Meta); die maßgebliche Quelle ist react.dev.
Drei Eigenschaften machen React aus:
- Deklarativ: Du beschreibst das Ergebnis für einen Zustand, nicht den Weg dorthin.
- Komponentenbasiert: Die Oberfläche besteht aus wiederverwendbaren Bausteinen. Der Zustand lebt in den Komponenten, nicht im DOM.
- Plattformübergreifend: React-Anwendungen laufen in erster Linie im Browser; mit React Native entstehen aus denselben Konzepten Apps für Android und iOS.
Zur Einordnung die wichtigsten Alternativen:
| Bibliothek/Framework | Herkunft | Kurzcharakteristik |
|---|---|---|
| React | Meta | UI-Bibliothek, großes Ökosystem |
| Angular | vollständiges Framework auf TypeScript-Basis, viel Struktur, steilere Lernkurve | |
| Vue | Evan You | mit React vergleichbar, eigene Template-Syntax, sanfter Einstieg |
| Svelte | Rich Harris | verschiebt die Arbeit in den Compiler, dadurch sehr schlanke Ergebnisse |
Gebaut werden damit typischerweise Single Page Applications: Der Browser lädt das HTML-Grundgerüst einmal und holt danach nur noch Daten nach, während JavaScript die Anzeige austauscht. Der Seitenwechsel ohne Neuladen ist das sichtbare Merkmal. Dass Next.js diese strikte Trennung später wieder aufweicht (Teile der Seite entstehen dort am Server), ist kein Widerspruch, sondern die Antwort auf die Schwächen reiner SPAs; dazu Kapitel 8.
Wo begegnet dir das? In Webanwendungen, die beim Klicken nicht neu laden: Wechselst du in einem Web-Mailprogramm vom Posteingang zu einer Nachricht, bleibt die Seite stehen, und nur der Inhaltsbereich wird ausgetauscht.
React JS Explained In 10 Minutes von Dennis Ivy, ein Überblick in zehn Minuten (Englisch):
Der Denkwechsel: deklarativ statt imperativ
Abschnitt betitelt „Der Denkwechsel: deklarativ statt imperativ“Ein Zähler, einmal imperativ mit direkter DOM-Manipulation, einmal deklarativ mit React:
// imperative: describe the STEPSconst button = document.querySelector("#increment");const label = document.querySelector("#count");let count = 0;button.addEventListener("click", () => { count += 1; label.textContent = String(count); // manual UI update, easy to forget});Beispielprojekt: 07_react_grundlagen_examples/ex01_imperative_counter
// declarative: describe the RESULT for a given statefunction Counter() { const [count, setCount] = useState(0); return <button onClick={() => setCount(count + 1)}>Count: {count}</button>;}Beispielprojekt: 07_react_grundlagen_examples/ex02_declarative_counter
Die Schreibweise im zweiten Block (HTML-artige Tags im Code, useState) lernst du in den Einheiten 7.2 und 7.4 im Detail; hier zählt nur der Unterschied im Denken. Im imperativen Stil bist du dafür verantwortlich, dass Zustand und Anzeige zusammenpassen, an jeder einzelnen Stelle, die den Zustand ändert. Vergessene Updates sind die Standardfehlerquelle wachsender Oberflächen. Im deklarativen Stil gibt es diese Fehlerklasse nicht: Die Komponente beschreibt die Anzeige für jeden Zustand, und React führt nach jeder Zustandsänderung die nötigen DOM-Änderungen selbst durch.
flowchart LR
accTitle: Die Oberfläche als Funktion des Zustands
state["Zustand<br/>count = 3"] --> comp["Komponente<br/>Counter()"]
comp --> ui["Oberfläche<br/>Count: 3"]
Abb. 7.2: Gleicher Zustand, gleiche Oberfläche; die Komponente ist die Funktion dazwischen (eigene Darstellung).
Daraus folgt eine Regel, die ab jetzt gilt:
Auflösung
Imperativ: ein neuer Listener für “Zurücksetzen”, und in jedem Listener müssen jetzt beide Anzeigen aktualisiert werden, also vier Update-Zeilen statt einer. Vergisst du eine, zeigen Kopfzeile und Knopf verschiedene Zahlen. Deklarativ: ein zweiter Knopf, der setCount(0) ruft, und die Zahl steht ein zweites Mal im zurückgegebenen Markup. Aktualisiert wird nichts von Hand; beide Anzeigen folgen aus demselben count.
DOM und Virtual DOM
Abschnitt betitelt „DOM und Virtual DOM“Das DOM ist ein Baum, in dem jedes Element (<div>, <p>, <img>), jedes Attribut und jeder Text ein Knoten ist. JavaScript kann diesen Baum lesen und verändern; genau das macht eine Webseite dynamisch. Der Preis: Jede Änderung am echten DOM kann den Browser zwingen, Layout und Anzeige neu zu berechnen. Wer bei einer Listenänderung die ganze Liste neu aufbaut, bezahlt das mit spürbarem Ruckeln.
Der Virtual DOM ist eine leichtgewichtige Abbildung dieses Baums als gewöhnliche JavaScript-Objekte im Speicher. React arbeitet zuerst auf der Abbildung und überträgt danach nur die tatsächlichen Unterschiede auf das echte DOM:
flowchart LR
accTitle: Vom Zustand zum echten DOM über den Virtual DOM
state["State/Props<br/>ändern sich"] --> render["Komponenten<br/>neu rendern"]
render --> vnew["neuer<br/>Virtual DOM"]
vold["alter<br/>Virtual DOM"] --> diff["Vergleich<br/>(Diffing)"]
vnew --> diff
diff --> patch["Reconciliation:<br/>nur die Unterschiede"]
patch --> dom["echtes DOM"]
Abb. 7.3: React vergleicht alten und neuen Virtual DOM und ändert im echten DOM nur das Nötige (eigene Darstellung).
-
Erstes Rendern: Die gesamte Oberfläche entsteht als Virtual DOM und wird einmal vollständig ins echte DOM übertragen.
-
Änderung von State oder Props: Die betroffenen Komponenten werden erneut ausgeführt und erzeugen einen neuen Virtual DOM; das echte DOM bleibt vorerst unberührt.
-
Vergleich (Diffing): React vergleicht den neuen Virtual DOM mit dem vorherigen und ermittelt die Unterschiede.
-
Abgleich (Reconciliation): Aus den Unterschieden entsteht die Liste nötiger Änderungen, typischerweise ein paar Textknoten und Attribute, nicht der ganze Teilbaum.
-
Übertragung: Nur diese Änderungen wandern ins echte DOM.
Genauer erklärt: Der Gewinn liegt nicht darin, dass React “schneller rechnet”; die Vergleichsarbeit kostet ja zusätzlich Zeit. Der Gewinn liegt darin, dass React weiß, was sich geändert hat, und deshalb minimal eingreifen kann. Ändert sich in einer Liste mit 200 Einträgen ein einziger Titel, schreibt React genau einen Textknoten neu. Eine handgeschriebene Lösung, die innerHTML neu setzt, baut 200 Elemente ab und wieder auf, samt Scrollposition, Tastaturfokus und markiertem Text. Für den Vergleich braucht React bei Listen Anhaltspunkte, welches Element im alten und im neuen Baum dasselbe ist; dafür gibt es das key-Attribut (Einheit 7.3).
Wo begegnet dir das? Tippst du in ein Suchfeld mit Live-Vorschlägen, ändert sich bei jedem Tastendruck die Vorschlagsliste. Würde die Seite dabei das Suchfeld neu aufbauen, verlörest du nach jedem Buchstaben den Cursor; weil nur die Unterschiede übertragen werden, bleibt das Feld unberührt.
Das Projekt: Vite, React und TypeScript
Abschnitt betitelt „Das Projekt: Vite, React und TypeScript“React allein ist ein Paket aus der npm-Registry. Damit daraus eine lauffähige Anwendung wird, braucht es ein Werkzeug, das die Dateien bündelt, den Entwicklungsserver startet und TypeScript und JSX in browsertaugliches JavaScript übersetzt. Dieses Werkzeug ist Vite.
-
Projekt anlegen. Im Projektordner (ohne Leerzeichen im Pfad, siehe Kapitel 1):
Terminal-Fenster npm create vite@latest react-basics -- --template react-tscd react-basicsnpm installDie Vorlage heißt
react-ts, nichtreact: Damit ist TypeScript von der ersten Datei an eingerichtet, samttsconfig.json, Typpaketen und.tsx-Dateien. -
Entwicklungsserver starten.
Terminal-Fenster npm run devVite meldet eine Adresse, üblicherweise
http://localhost:5173. Die Seite aktualisiert sich bei jeder gespeicherten Änderung selbst (Hot Module Replacement), ohne Neuladen und ohne Verlust des aktuellen Zustands. -
Produktionsfassung bauen und ansehen.
Terminal-Fenster npm run build # type-checks, then writes the optimized bundle to dist/npm run preview # serves dist/ at http://localhost:4173Diese beiden Befehle sind die Gegenprobe vor jeder Abgabe.
npm run buildführt zuersttsc -baus und bricht bei jedem Typfehler ab; der Entwicklungsserver tut das nicht (Abschnitt Werkzeuge unter der Haube).
Die Ordnerstruktur nach dem Anlegen, auf das Wesentliche gekürzt:
react-basics/├── index.html entry point of the page, contains <div id="root">├── package.json dependencies and scripts├── tsconfig.app.json TypeScript settings for src/├── vite.config.ts Vite settings├── public/ files served as they are (images, downloads)└── src/ ├── main.tsx mounts the React app into #root ├── App.tsx the root component ├── index.css global styles └── components/ one file per component (created by you)Die Vorlage bringt eine Beispielseite mit Logos und einem Zähler mit. Sie ist zum Aufräumen gedacht: App.tsx auf ein leeres Gerüst zurückstutzen, die Beispielbilder aus src/assets/ löschen, dann mit der eigenen Anwendung beginnen.
Zwei Dateien lohnen einen Blick. index.html enthält genau einen leeren Container, in den React die gesamte Anwendung hängt:
<div id="root"></div><script type="module" src="/src/main.tsx"></script>Und main.tsx stellt die Verbindung her. Das ist die einzige Stelle im ganzen Projekt, an der ein DOM-Element direkt angesprochen wird:
import { StrictMode } from "react";import { createRoot } from "react-dom/client";import App from "./App";
createRoot(document.getElementById("root")!).render( <StrictMode> <App /> </StrictMode>,);Beispielprojekt: 07_react_grundlagen_examples/ex03_react_basics
createRoot(...) übernimmt den Container, render(...) zeichnet die Wurzelkomponente hinein. Ab hier kommt kein document mehr vor. StrictMode ist eine Entwicklungshilfe: React führt Komponenten darin absichtlich doppelt aus, um unsaubere Seiteneffekte sichtbar zu machen. Deshalb erscheint im Entwicklungsmodus manche console.log-Ausgabe zweimal; im fertigen Build passiert das nicht.
flowchart LR
accTitle: Wie die Anwendung in die Seite kommt
html["index.html<br/>div id=root"] --> main["main.tsx<br/>createRoot(...)"]
main --> app["App.tsx<br/>Wurzelkomponente"]
app --> comps["eigene Komponenten<br/>in src/components/"]
Abb. 7.4: Ein leerer Container, eine Startdatei, ab dann nur noch Komponenten (eigene Darstellung).
Werkzeuge unter der Haube
Abschnitt betitelt „Werkzeuge unter der Haube“Browser verstehen weder JSX noch TypeScript und laden ungern mehrere hundert einzelne Dateien. Zwischen deinem Quellcode und der ausgelieferten Seite steht deshalb immer ein Werkzeug. Die Begriffe, die dir dabei begegnen:
| Begriff | Was es tut |
|---|---|
| Transpiler | übersetzt eine Sprache in eine andere auf demselben Abstraktionsniveau, hier TypeScript und JSX nach browsertauglichem JavaScript |
| Bundler | fasst die vielen Quelldateien und ihre Abhängigkeiten zu wenigen ausgelieferten Dateien zusammen und wirft Unbenutztes weg |
| Vite | steuert beides: Entwicklungsserver mit Hot Module Replacement und Produktions-Build |
| Oxc, Rolldown | die in Rust geschriebenen Werkzeuge, die Vite 8 intern verwendet: Oxc transpiliert (und stellt mit oxlint auch den Linter der Vorlage), Rolldown bündelt |
| esbuild, Rollup | die Vorgänger in genau diesen Rollen, in älteren Vite-Versionen und vielen anderen Projekten weiterhin im Einsatz |
| Babel, Webpack | die Klassiker aus der Zeit vor Vite: Babel als Transpiler, Webpack als Bundler |
Welches Werkzeug Vite intern nutzt, ändert sich von Version zu Version; die Rollen bleiben dieselben. Ein Detail daraus zählt für die Fehlersuche: Der Transpiler entfernt die Typen, er prüft sie nicht.
flowchart LR
accTitle: Zwei Wege vom Quellcode, nur einer prüft Typen
src["src/*.tsx"] --> dev["npm run dev:<br/>Typen entfernen"]
dev --> browser["Browser zeigt<br/>die Seite"]
src --> tsc["npm run build:<br/>zuerst tsc -b"]
tsc -- "Typfehler" --> stop["Abbruch"]
tsc -- "fehlerfrei" --> bundle["Bündeln nach dist/"]
Abb. 7.5: Der Entwicklungsserver zeigt die Seite auch mit Typfehlern; erst der Build prüft (eigene Darstellung).
Ein Typfehler bricht den Entwicklungsserver deshalb nicht ab, und die Seite läuft scheinbar weiter. Sichtbar wird er in VS Code (rote Wellenlinie), bei npm run build (dort läuft tsc -b vor dem Bündeln) und bei einem ausdrücklichen npx tsc -b. Wer sich allein auf den laufenden Browser verlässt, übersieht Typfehler zuverlässig; der Build-Lauf gehört deshalb vor jede Abgabe.
Stolperfallen
Abschnitt betitelt „Stolperfallen“- Vorlage
reactstattreact-ts: Das Projekt entsteht in JavaScript, ohnetsconfig.jsonund ohne.tsx-Dateien. - Direkter DOM-Zugriff in einer Komponente:
document.querySelector(...)funktioniert scheinbar und bricht beim nächsten Rendern. - Nur im Entwicklungsserver getestet: Typfehler bleiben unbemerkt, bis
npm run buildabbricht. - Doppelte Konsolenausgaben für einen Fehler gehalten:
StrictModeführt Komponenten im Entwicklungsmodus absichtlich doppelt aus. - Leerzeichen im Projektpfad: Manche Werkzeuge der Kette kommen damit nicht zurecht (Kapitel 1).
Zusatzmaterialien
Abschnitt betitelt „Zusatzmaterialien“- react.dev: Learn React - die offizielle Einführung, vollständig und mit Beispielen zum Ausprobieren im Browser.
- Vite: Getting Started - Vorlagen, Skripte und der
public/-Ordner für eigene Bilder und Dateien. - React Developer Tools - die Browser-Erweiterung, die den Komponentenbaum samt Props und State anzeigt.
Zum Anhören
Abschnitt betitelt „Zum Anhören“Du kannst dir diese Einheit kostenlos mit der Vorlesefunktion deines Browsers oder Betriebssystems vorlesen lassen (etwa „Laut vorlesen” in Edge), ohne Konto und ohne Upload; die Codebeispiele liest du dabei am Bildschirm mit. Freiwillig kannst du mit Google NotebookLM (Google-Konto nötig) aus diesem öffentlichen Text eine gesprochene Zusammenfassung erzeugen, auch auf Deutsch.
Lernergebnisse
Abschnitt betitelt „Lernergebnisse“Du kannst jetzt:
- erklären, was React ist, und es von Frameworks wie Angular abgrenzen.
- das deklarative Modell (“die Oberfläche ist eine Funktion des Zustands”) gegen direkte DOM-Manipulation abgrenzen.
- die Rolle des Virtual DOM beim Aktualisieren der Seite beschreiben.
- ein React-Projekt mit Vite und TypeScript anlegen, starten und für die Auslieferung bauen.
Passende Übungen
Abschnitt betitelt „Passende Übungen“- Aufgabe 07-1a - Komponenten-Baukasten, Abschnitt Allgemein: das Vite-Projekt
uebung-07-1anach diesem Muster anlegen und aufräumen; die Aufgaben 07-4a und 07-6a entstehen genauso
Quellen
Abschnitt betitelt „Quellen“- React als Bibliothek, deklaratives Modell,
createRootundStrictMode→ react.dev: Learn React, createRoot, StrictMode - Alternativen → angular.dev, vuejs.org, svelte.dev
- Projektanlage, Skripte, Ports 5173 und 4173 → Vite: Getting Started; Vorlage
react-tsund Skript"build": "tsc -b && vite build"→ eigener Test mitnpm create vite@latest(Vite 8.3.4, Oktober 2026) - Oxc und Rolldown in Vite 8 → Vite: Getting Started;
oxlintals Linter der Vorlage → eigener Test (Oktober 2026) - Video React JS Explained In 10 Minutes → Dennis Ivy auf YouTube: s2skans2dP4
- Abb. 7.1 (Anzeigetafel), Abb. 7.2 (Funktion des Zustands), Abb. 7.3 (Virtual DOM), Abb. 7.4 (Einstieg der Anwendung), Abb. 7.5 (dev und build) → eigene Darstellung, alle als Mermaid-Diagramm
Autoren
Abschnitt betitelt „Autoren“- Oliver Maurhart (MAO)
- Michael Gabriel (GAM)
CC-BY-SA