JavaScript in JSX
Im letzten Kapitel hast du gesehen, dass JSX-Kommentare geschweifte Klammern verwenden. Aber Kommentare sind nur der Anfang — geschweifte Klammern öffnen ein Fenster zu JavaScript mitten in deinem Markup.
Strings mit Anführungszeichen
Abschnitt betitelt „Strings mit Anführungszeichen“Wenn du ein String-Attribut an JSX übergeben willst, verwendest du einfache oder doppelte Anführungszeichen — genau wie in HTML:
function StudentCard() { return <img src="dan.jpg" alt="Dan Abramov" />;}Hier sind "dan.jpg" und "Dan Abramov" feste Strings. Aber was, wenn du den Namen oder die Bild-URL dynamisch setzen willst? Dann ersetzt du die Anführungszeichen durch geschweifte Klammern:
function StudentCard() { const name = "Dan Abramov"; const imageUrl = "dan.jpg";
return <img src={imageUrl} alt={name} />;}Statt src="dan.jpg" schreibst du src={imageUrl} — und JSX liest den Wert aus der Variable.
Geschweifte Klammern: Ein Fenster zu JavaScript
Abschnitt betitelt „Geschweifte Klammern: Ein Fenster zu JavaScript“Geschweifte Klammern können mehr als nur Variablen auslesen. Du kannst jeden JavaScript-Ausdruck in JSX einbetten — Berechnungen, Methodenaufrufe, Funktionsaufrufe:
function StudentCard() { const name = "Dan Abramov";
return <h1>{name.toUpperCase()}</h1>;}{name.toUpperCase()} ruft die Methode auf und setzt das Ergebnis ("DAN ABRAMOV") in das JSX ein. Auch eigene Funktionen funktionieren:
function formatStudentId(id) { return "STU-" + id.toString().padStart(4, "0");}
function StudentCard() { return <p>ID: {formatStudentId(42)}</p>;}{formatStudentId(42)} ruft die Funktion auf und setzt "STU-0042" in das JSX ein.
Auch der Ternary-Operator funktioniert — schließlich ist er ein Ausdruck:
function Greeting() { const hour = new Date().getHours();
return <p>{hour < 12 ? "Guten Morgen" : "Guten Tag"}, Dan!</p>;}{hour < 12 ? "Guten Morgen" : "Guten Tag"} wertet die Bedingung aus und setzt den passenden String ein.
Weil JSX selbst ein JavaScript-Ausdruck ist, kann ein Ternary auch JSX zurückgeben:
function Greeting() { const hour = new Date().getHours();
return ( <div> {hour < 12 ? <p>Guten Morgen, es ist <strong>{hour} Uhr</strong></p> : <p>Guten Tag, es ist <strong>{hour} Uhr</strong></p> } </div> );}Hier steckt JSX innerhalb von geschweiften Klammern, und in diesem JSX wieder geschweifte Klammern mit {hour}. Das funktioniert, weil JSX nur React.createElement-Aufrufe sind — also ganz normales JavaScript.
Wo geschweifte Klammern funktionieren
Abschnitt betitelt „Wo geschweifte Klammern funktionieren“Du kannst geschweifte Klammern an genau zwei Stellen in JSX verwenden:
- Als Text innerhalb eines JSX-Tags:
<h1>{name}</h1> - Als Attributwert direkt nach dem
=:src={imageUrl}
Alles andere führt zu einem Fehler. Zum Beispiel kannst du keinen Tag-Namen dynamisch setzen:
// Fehler! Tag-Namen können nicht dynamisch seinconst tag = "h1";return <{tag}>Hallo</{tag}>;Und Achtung: Geschweifte Klammern innerhalb von Anführungszeichen werden als normaler Text behandelt:
// Gibt den Text "{imageUrl}" aus, nicht den Wert der Variable!<img src="{imageUrl}" />Nicht alles ist ein String
Abschnitt betitelt „Nicht alles ist ein String“Bisher haben wir nur Strings in geschweifte Klammern gesetzt. Aber viele DOM-Properties sind gar keine Strings — und JSX kann alle JavaScript-Typen übergeben.
Zahlen — colSpan erwartet eine Zahl:
<td colSpan={3}>Zusammengefasste Zelle</td>Booleans — disabled erwartet true oder false:
<button disabled={true}>Gesperrt</button><button disabled={false}>Klick mich</button>Objekte — style erwartet ein Objekt mit CSS-Properties. JavaScript-Objekte verwenden ebenfalls geschweifte Klammern: { color: "#333" }. Um ein Objekt in JSX zu übergeben, brauchst du deshalb zwei Paar geschweifte Klammern — das äußere Paar öffnet das JavaScript-Fenster, das innere definiert das Objekt:
function StudentCard() { return ( <div style={{ backgroundColor: "#f0f0f0", color: "#333" }}> <h1>Dan Abramov</h1> </div> );}{{ sieht auf den ersten Blick nach spezieller Syntax aus — ist es aber nicht. Es ist einfach ein Objekt { backgroundColor: "#f0f0f0", color: "#333" } innerhalb der JSX-Klammern { }.
className: CSS-Klassen dynamisch setzen
Abschnitt betitelt „className: CSS-Klassen dynamisch setzen“Die DOM-Property className ist ein String — genau wie das HTML-Attribut class. Im einfachsten Fall übergibst du einen festen String:
<div className="card">...</div>Aber weil className ein String ist, kannst du mit JavaScript-Ausdrücken beliebig dynamische Klassen bauen.
Ternary — eine Klasse abhängig von einer Bedingung:
<div className={isActive ? "card active" : "card"}>...</div>Array mit join — mehrere Klassen zusammensetzen:
<div className={["card", "highlighted", "rounded"].join(" ")}>...</div>// ergibt: className="card highlighted rounded"Das wird nützlich, wenn manche Klassen bedingt hinzukommen:
<div className={[ "card", isActive && "active", isHighlighted && "highlighted",].filter(Boolean).join(" ")}>...</div>filter(Boolean) entfernt die false-Werte — übrig bleiben nur die Klassen, deren Bedingung erfüllt ist.
Hilfsfunktion mit Objekt — für komplexere Fälle ist eine Funktion übersichtlicher:
function classNames(classes) { return Object.entries(classes) .filter(([, active]) => active) .map(([name]) => name) .join(" ");}
<div className={classNames({ card: true, active: isActive, highlighted: isHighlighted,})}>...</div>Jeder Schlüssel ist ein Klassenname, der Wert entscheidet, ob er aktiv ist. Das Muster ist so verbreitet, dass es dafür fertige Bibliotheken gibt (z.B. clsx).
Alles zusammen: Daten in einem Objekt
Abschnitt betitelt „Alles zusammen: Daten in einem Objekt“Statt Daten über viele Variablen zu verstreuen, kannst du sie in einem Objekt zusammenfassen und daraus in JSX lesen:
const student = { name: "Dan Abramov", imageUrl: "dan.jpg", fachrichtung: "Informatik", theme: { backgroundColor: "#f0f0f0", color: "#333", },};
function StudentCard() { return ( <div style={student.theme}> <img src={student.imageUrl} alt={student.name} /> <h1>{student.name}</h1> <p>Fachrichtung: {student.fachrichtung}</p> </div> );}Alle Daten kommen aus dem student-Objekt:
{student.name}→ der Name als Text{student.imageUrl}→ die Bild-URL als Attribut{student.fachrichtung}→ die Fachrichtung als Textstyle={student.theme}→ ein ganzes Style-Objekt als Attribut
So hältst du Daten und Darstellung sauber getrennt — eine Grundidee, die in React immer wieder auftaucht.