Conditional Rendering ist die Frage: Wie zeige ich je nach Zustand andere UI? React kennt dafür keine spezielle Syntax — es nutzt die JavaScript-Bordmittel. Vier Patterns decken praktisch alle Fälle ab: if/else vor dem return (für Branches mit mehreren Statements), Ternary cond ? A : B (für Inline-Branches im JSX), Short-Circuit cond && A (für optionales Rendern eines einzelnen Elements), und Early Return (eine ganze Komponente liefert je nach Bedingung etwas Anderes). Welche Form passt, hängt vom Kontext ab.

if/else vor dem return

Wenn die Bedingung komplex ist oder mehrere Variablen vorbelegt werden müssen, kommt klassisches if/else vor dem return zum Einsatz.

TypeScript Greeting.jsx
const Greeting = () => {
    const username = 'John';
    const stunde = new Date().getHours();

    let greeting;
    if (stunde < 12) {
        greeting = 'Guten Morgen';
    } else if (stunde < 18) {
        greeting = 'Guten Tag';
    } else {
        greeting = 'Guten Abend';
    }

    return <p>{greeting}, {username}</p>;
};

Vorteil: alle JavaScript-Konstrukte sind verfügbar (if/else if/else, switch, Block-Statements). Nachteil: man muss eine Variable vor dem return deklarieren.

Ternary im JSX

In JSX selbst sind nur Expressions erlaubt — keine if-Statements. Der Ternary-Operator cond ? A : B ist die Standard-Form, eine Bedingung inline zu schreiben.

TypeScript Inline.jsx
const Greeting = ({ username }) => {
    const stunde = new Date().getHours();

    return (
        <>
            {stunde < 12 ? (
                <p>Guten Morgen, {username}</p>
            ) : stunde < 18 ? (
                <p>Guten Tag, {username}</p>
            ) : (
                <p>Guten Abend, {username}</p>
            )}
        </>
    );
};

Verschachtelte Ternaries sind möglich, werden aber schnell unleserlich. Faustregel: maximal zwei Stufen. Bei mehr Branches: in eine Helper-Funktion auslagern oder die if/else-Variante davor nutzen.

&&-Short-Circuit für optionales Rendern

Wenn nur eine Sache gerendert werden soll, falls eine Bedingung wahr ist, ist cond && JSX die kürzeste Form.

TypeScript OptionalList.jsx
const ItemList = ({ items }) => {
    return (
        <div className="items-wrapper">
            {items.length > 0 && (
                <ul>
                    {items.map((item, idx) => (
                        <li key={idx}>{item}</li>
                    ))}
                </ul>
            )}
        </div>
    );
};

Die Liste wird nur gerendert, wenn items.length > 0 truthy ist. Andernfalls produziert && false — und React rendert false als nichts.

Wichtige Falle: && mit einer Zahl kann unbeabsichtigt rendern.

TypeScript And-Falle.jsx
// FALLE: bei items.length === 0 rendert React die 0!
<div>{items.length && <List items={items} />}</div>
// → DOM enthält "0" als Textknoten

// KORREKT: explizite Boolean-Konvertierung
<div>{items.length > 0 && <List items={items} />}</div>
// oder
<div>{!!items.length && <List items={items} />}</div>

&& gibt den linken Operanden zurück, wenn er falsy ist — und 0 ist zwar falsy, aber React rendert es als String "0". Daher immer mit explizitem Vergleich arbeiten.

Ternary für Fallback-UI

Wenn man je nach Zustand zwei verschiedene UIs anzeigen will (z.B. eine Liste oder eine „Leer"-Meldung), ist Ternary die saubere Form.

TypeScript ListOrEmpty.jsx
const ItemList = ({ items }) => {
    return (
        <div className="items-wrapper">
            {items.length > 0 ? (
                <ul>
                    {items.map((item, idx) => (
                        <li key={idx}>{item}</li>
                    ))}
                </ul>
            ) : (
                <p>Keine Elemente vorhanden</p>
            )}
        </div>
    );
};

Verbreitetes Pattern für Loading-States: isLoading ? <Spinner /> : <Content />.

Early Return — ganze Komponente entscheidet

Wenn eine Komponente komplett unterschiedliche UI rendert je nach Zustand, ist ein Early Return vor dem Haupt-Return oft die lesbarste Form.

TypeScript UserPage.jsx
const UserPage = ({ user, isLoading, error }) => {
    if (isLoading) return <Spinner />;
    if (error) return <ErrorBanner message={error.message} />;
    if (!user) return <p>Bitte einloggen.</p>;

    return (
        <div>
            <h1>{user.name}</h1>
            <p>{user.email}</p>
        </div>
    );
};

Das Pattern heißt auch Guard Clauses — alle Edge-Cases werden vorab abgefangen, der Haupt-Pfad bleibt geradeaus und übersichtlich.

Lookup-Map statt verschachtelter if-Kette

Bei vielen diskreten Zuständen lohnt sich eine Lookup-Map — ein Object, das pro Schlüssel die zugehörige Komponente liefert.

TypeScript StatusIcon.jsx
const icons = {
    success: <CheckIcon />,
    warning: <WarnIcon />,
    error: <ErrorIcon />,
    info: <InfoIcon />,
};

const StatusIcon = ({ type }) => {
    return icons[type] ?? <DefaultIcon />;
};

Vorteil gegenüber einer langen switch- oder if-Kette: neue Stati hinzufügen heißt eine Zeile im Object, keine neue if-Verzweigung.

Verstecken vs. nicht rendern

Wichtige Unterscheidung: nicht rendern (cond && <X />) vs. rendern und verstecken (<X style={{display: 'none'}}/>).

  • Nicht rendern: Komponente existiert gar nicht im DOM. State und Effects sind weg, beim nächsten true wird sie neu mounted.
  • Verstecken: Komponente bleibt im DOM, State bleibt erhalten, nur visuell weg.
TypeScript Versteckt.jsx
// Nicht gerendert — State wird verworfen
{open && <ExpensiveModal />}

// Gerendert, aber versteckt — State bleibt
<ExpensiveModal hidden={!open} />

Die richtige Wahl hängt vom Use-Case ab. Bei teuren Komponenten mit wichtigem State (z.B. Modals mit Formular-Eingaben): verstecken statt unmounten.

Häufige Stolperfallen

cond && Element bei einer Zahl rendert die Zahl als Text.

{items.length && <List />} bei items.length === 0 rendert die 0 als Textknoten. Lösung: items.length > 0 && ... oder !!items.length && .... Klassische React-Falle.

Mehrfach verschachtelte Ternaries — unlesbar.

Drei oder mehr Ternaries hintereinander sind schwer zu lesen. Faustregel: ab zwei Stufen die Logik in eine Helper-Funktion auslagern oder Early-Return im Komponenten-Body nutzen.

if-Statement im JSX ist ein Syntax-Fehler.

JSX akzeptiert nur Expressions. {if (x) ...} ist ungültig. Wer Branching im JSX braucht: Ternary, &&, IIFE oder Auslagerung in eine Funktion.

null-Render ist erlaubt — undefined und true/false sind es auch.

Eine Komponente darf return null zurückgeben, um nichts zu rendern. Auch true, false, undefined werden zu „nichts". Strings (auch leere) und Numbers (auch 0) dagegen werden gerendert.

Early Return verliert lokale Hooks-Aufrufe NICHT.

Wer mehrere Hooks am Anfang einer Komponente ruft und dann Early-Return macht, ist auf der sicheren Seite — solange die Hook-Reihenfolge konstant bleibt. NICHT erlaubt: Hooks NACH einem Early Return aufrufen. Das verletzt die Hook-Regeln.

Bedingte Hook-Aufrufe — verboten.

if (cond) useEffect(...) ist ein React-Fehler. Hooks müssen IMMER in derselben Reihenfolge aufgerufen werden. Die Bedingung gehört INNERHALB des Hook-Callbacks oder als Dependency, nicht um den Hook herum.

Verstecken (display:none) vs. Unmount — State-Konsequenz.

Beim Unmounten geht aller lokaler State und alle Effect-Cleanups verloren. Beim Verstecken bleibt alles. Bei teuren Komponenten mit User-Eingabe: lieber verstecken; bei einfachen UI-Elementen: Unmount ist okay.

Key bei dynamischen Branches — Reset des State erzwingen.

Beim Wechsel zwischen zwei Komponenten kann ein expliziter key erzwingen, dass React beim Branch-Wechsel komplett neu mountet. Praktisch beim Form-Reset zwischen verschiedenen Modes.

Weiterführende Ressourcen

Externe Quellen

/ Weiter

Zurück zu Components

Zur Übersicht