Zum Inhalt springen
aviral gupta

// B2.4 · ca. 30 Min. · Einstieg

Bedingtes Rendern

Nach dieser Lektion zeigen Sie je nach Bedingung anderes JSX, mit if, null, dem ternären ? : und &&, ohne verirrte 0.

Lektion 4 von 6 in B2 Die Oberfläche beschreiben

Danach können Sie

  • Mit if und return anderes JSX zurückgeben, oder null, um nichts zu rendern
  • Mit dem ternären ? : im JSX zwischen zwei Stücken JSX wählen
  • JSX mit && ohne verirrte 0 einfügen oder in einer let-Variablen aufbauen
  1. Aufwärmen · Aufgabe 1 von 7

    Zum Aufwärmen aus Lektion B2.3: children und ein Standardwert. Welchen Text zeigt App?

    function Label({ color = 'gray', children }) {
      return <b>{children} ({color})</b>;
    }
    
    function App() {
      return <Label>Sale</Label>;
    }
  2. Vorhersagen · Aufgabe 2 von 7

    Sagen Sie voraus, bevor Sie weiterlesen. Es gibt keine neuen Nachrichten (Ergebnis auf Englisch: nothing = nichts). Welchen Text zeigt Inbox?

    const messageCount = 0;
    
    function Inbox() {
      return <div>{messageCount && <p>New messages</p>}</div>;
    }
  3. Üben · Aufgabe 3 von 7

    Ergänzen Sie den Operator, der das Häkchen nur zeigt, wenn isPacked true ist, und sonst nichts.

    <li>{name} {isPacked ____ '✅'}</li>
    <li>{name} {isPacked '✅'}</li>
  4. Üben · Aufgabe 4 von 7

    Ordnen Sie jedem Stück Code zu, was es tut.

  5. Üben · Aufgabe 5 von 7

    Eine Elternkomponente rendert <Item name="Helmet" isPacked={true} />. Welches HTML setzt sie in #root?

    function Item({ name, isPacked }) {
      let content = name;
      if (isPacked) {
        content = <del>{name}</del>;
      }
      return <li>{content}</li>;
    }
  6. Denksport · Aufgabe 6 von 7

    Knobelaufgabe. Item hat ein if, aber danach kein return. Wie viele <li>-Elemente rendert PackingList?

    function Item({ name, isPacked }) {
      if (isPacked) {
        return <li>{name} ✅</li>;
      }
    }
    
    function PackingList() {
      return (
        <ul>
          <Item name="Tent" isPacked={true} />
          <Item name="Map" isPacked={false} />
        </ul>
      );
    }
  7. Anwenden · Aufgabe 7 von 7

    Mini-Aufgabe: eine Aufgabenliste. Schreiben Sie in main.jsx eine Komponente Task mit den Props title, isDone und dueToday. Eine Aufgabe ohne Titel rendert nichts (return null). Eine erledigte Aufgabe zeigt ihren Titel mit <del> durchgestrichen, gewählt mit if und einer let-Variablen; jede Aufgabe zeigt ✅ oder ⏳ mit einem ternären Ausdruck; eine heute fällige Aufgabe ergänzt mit && " today". Der Default-Export rendert drei Tasks, einen davon mit leerem Titel, und eine Zeile zu überfälligen Aufgaben, die keine verirrte 0 zeigen darf, wenn es keine gibt.

    Prüfen Sie Ihr Ergebnis anhand dieser Liste

Selbst programmieren

Lesen Sie das ausgearbeitete Beispiel und lösen Sie dann die Übungen. Ihr Code läuft in Ihrem Browser oder auf Ihrem Computer und wird nie hochgeladen.

Ausgearbeitetes Beispiel

Alex’ Packliste

Eine Packliste im Stil des Beispiels auf react.dev, mit allen vier Werkzeugen. Item streicht gepackte Items mit einem ternären Ausdruck durch. Note gibt null zurück, wenn es keinen Text hat, deshalb hinterlässt die leere Notiz keine Spur. Summary beginnt eine let-Variable mit einer Meldung und ersetzt sie, wenn noch etwas fehlt. Die letzte Zeile verwendet urgent > 0 &&, mit urgent = 0 erscheint also nichts, keine 0.

main.jsx

function Item({ name, isPacked }) {
  return (
    <li className="item">
      {isPacked ? <del>{name + ' ✅'}</del> : name}
    </li>
  );
}

function Note({ text }) {
  if (!text) {
    return null;
  }
  return <p className="note">{text}</p>;
}

function Summary({ left }) {
  let message = 'Everything is packed.';
  if (left > 0) {
    message = left + ' left to pack.';
  }
  return <p>{message}</p>;
}

export default function PackingList() {
  const urgent = 0;
  return (
    <section>
      <h1>Alex's Packing List</h1>
      <ul>
        <Item name="Tent" isPacked={true} />
        <Item name="Sleeping bag" isPacked={true} />
        <Item name="Map" isPacked={false} />
      </ul>
      <Summary left={1} />
      <Note text="" />
      {urgent > 0 && <p>{urgent} urgent items!</p>}
    </section>
  );
}

Ausführen mit

npm run dev

Ausgabe

<!-- #root -->
<div id="root"><section><h1>Alex's Packing List</h1><ul><li class="item"><del>Tent ✅</del></li><li class="item"><del>Sleeping bag ✅</del></li><li class="item">Map</li></ul><p>1 left to pack.</p></section></div>
  • Die zwei gepackten Items sind mit <del> durchgestrichen; Map, nicht gepackt, zeigt nur seinen Namen.
  • Note gab für den leeren Text null zurück, deshalb erscheint kein <p class="note">.
  • Summary hat seine let-Variable neu zugewiesen, weil left 1 ist.
  • urgent > 0 ist false, und React rendert false als nichts; urgent && … hätte 0 gezeigt.
Ändern und ausführen

Tab rückt ein, Umschalt+Tab rückt aus. Um den Editor mit der Tastatur zu verlassen, drücken Sie Esc und dann Tab.

Beim ersten Ausführen lädt Ihr Browser React und den Compiler herunter, der JSX in JavaScript übersetzt (bis zu 2 MB), und speichert beides im Cache. Ihre Komponenten laufen in Ihrem Browser und bleiben auf Ihrem Gerät.

Ihre Seite

Ihre Seite läuft in einem abgeschotteten Rahmen. Sie hat keinen Zugriff auf diese Website, und ihr localStorage liegt nur für diesen Lauf im Speicher: Der nächste Lauf beginnt leer.

Führen Sie das Programm aus, um seine Seite hier zu sehen.

Übungen

Übung 1 von 2

Gepackte Items durchstreichen

Jedes Item in Alex’ Liste sieht gleich aus. Ändern Sie Item so, dass ein gepacktes Item seinen Namen und ein Häkchen zeigt, mit <del> durchgestrichen, etwa <del>Tent ✅</del>, und ein nicht gepacktes Item nur seinen Namen. Verwenden Sie den ternären Operator ? : im <li>. Behalten Sie den Namen Item und seinen Export: Die Tests rendern es mit eigenen Props.

Tab rückt ein, Umschalt+Tab rückt aus. Um den Editor mit der Tastatur zu verlassen, drücken Sie Esc und dann Tab.

Beim ersten Ausführen lädt Ihr Browser React und den Compiler herunter, der JSX in JavaScript übersetzt (bis zu 2 MB), und speichert beides im Cache. Ihre Komponenten laufen in Ihrem Browser und bleiben auf Ihrem Gerät.

Ihre Seite

Ihre Seite läuft in einem abgeschotteten Rahmen. Sie hat keinen Zugriff auf diese Website, und ihr localStorage liegt nur für diesen Lauf im Speicher: Der nächste Lauf beginnt leer.

Führen Sie das Programm aus, um seine Seite hier zu sehen.

Hinweise
  1. Hinweis 1

    Schreiben Sie im <li> {isPacked ? … : …}: der erste Teil für gepackte Items, der zweite für die anderen.

  2. Hinweis 2

    Der gepackte Teil ist JSX: <del>{name + ' ✅'}</del>. Der andere Teil ist einfach name.

  3. Hinweis 3

    Die ganze Zeile: {isPacked ? <del>{name + ' ✅'}</del> : name}.

Eine Lösung zeigen

Ein möglicher Lösungsweg. Ihrer kann anders aussehen und trotzdem alle Prüfungen bestehen.

export function Item({ name, isPacked }) {
  return (
    <li className="item">
      {isPacked ? <del>{name + ' ✅'}</del> : name}
    </li>
  );
}

export default function PackingList() {
  return (
    <section>
      <h1>Alex's Packing List</h1>
      <ul>
        <Item name="Tent" isPacked={true} />
        <Item name="Sleeping bag" isPacked={true} />
        <Item name="Map" isPacked={false} />
      </ul>
    </section>
  );
}
Auf dem eigenen Computer ausführen

Installieren Sie React 19.3 oder neuer. Speichern Sie diese Dateien in einem Ordner, öffnen Sie dort ein Terminal und führen Sie die Befehle unten aus.

main.jsx

// TODO: a packed item shows its name and a check mark, struck out with
// <del>: <del>Tent ✅</del>. An item that is not packed shows only its name.
export function Item({ name, isPacked }) {
  return <li className="item">{name}</li>;
}

export default function PackingList() {
  return (
    <section>
      <h1>Alex's Packing List</h1>
      <ul>
        <Item name="Tent" isPacked={true} />
        <Item name="Sleeping bag" isPacked={true} />
        <Item name="Map" isPacked={false} />
      </ul>
    </section>
  );
}

main.test.jsx

import {test} from 'node:test';
import assert from 'node:assert/strict';
import {render, screen} from '@testing-library/react';
import PackingList, {Item} from './main.jsx';

test('Ein gepacktes Item zeigt seinen Namen mit Häkchen', () => {
  render(<Item name="Tent" isPacked={true} />);
  const item = screen.getByRole('listitem').textContent;
  assert.equal(item, 'Tent ✅', 'das Item lautet ' + JSON.stringify(item));
});

test('Ein gepacktes Item ist mit <del> durchgestrichen', () => {
  render(<Item name="Tent" isPacked={true} />);
  const del = screen.getByRole('listitem').querySelector('del');
  assert.ok(del, 'im gepackten Item steht kein <del>');
  assert.equal(del.textContent, 'Tent ✅', 'das <del> lautet ' + JSON.stringify(del.textContent));
});

test('Ein nicht gepacktes Item zeigt nur seinen Namen', () => {
  render(<Item name="Map" isPacked={false} />);
  const item = screen.getByRole('listitem');
  assert.equal(item.textContent, 'Map', 'das Item lautet ' + JSON.stringify(item.textContent));
  assert.equal(item.querySelector('del'), null, 'das nicht gepackte Item ist durchgestrichen');
});

test('Die Liste streicht zwei ihrer drei Items durch', () => {
  render(<PackingList />);
  const struck = screen.getAllByRole('listitem').filter((li) => li.querySelector('del')).length;
  assert.equal(struck, 2, 'durchgestrichene Items: ' + struck);
});

Legen Sie main.jsx in einem Vite-React-Projekt (npm create vite@latest, Vorlage react) als App.jsx in src/ ab und starten Sie es mit npm run dev. React rendert es dort wie hier in <StrictMode>.

Programm ausführen:

npm run dev

Für die Prüfungen gibt es noch keinen Befehl auf Ihrem Computer. Sie stehen in main.test.jsx, geschrieben mit node:test und React Testing Library.

Übung 2 von 2

Eine Inbox ohne verirrte 0

Inbox zeigt, wie viele neue Nachrichten es gibt. Führen Sie es aus: Die leere Inbox zeigt unter ihrer Überschrift eine 0, und eine einzelne Nachricht heißt "messages". Beheben Sie beides: Bei 0 Nachrichten erscheint unter der Überschrift nichts; bei 1 steht "You have 1 new message"; sonst etwa "You have 3 new messages". Behalten Sie den Namen Inbox und seinen Export.

Tab rückt ein, Umschalt+Tab rückt aus. Um den Editor mit der Tastatur zu verlassen, drücken Sie Esc und dann Tab.

Beim ersten Ausführen lädt Ihr Browser React und den Compiler herunter, der JSX in JavaScript übersetzt (bis zu 2 MB), und speichert beides im Cache. Ihre Komponenten laufen in Ihrem Browser und bleiben auf Ihrem Gerät.

Ihre Seite

Ihre Seite läuft in einem abgeschotteten Rahmen. Sie hat keinen Zugriff auf diese Website, und ihr localStorage liegt nur für diesen Lauf im Speicher: Der nächste Lauf beginnt leer.

Führen Sie das Programm aus, um seine Seite hier zu sehen.

Hinweise
  1. Hinweis 1

    count && … ergibt 0, wenn count 0 ist, und React zeigt die Zahl. Setzen Sie links einen Boolean.

  2. Hinweis 2

    count > 0 && <p>…</p> rendert für 0 nichts, weil count > 0 false ist.

  3. Hinweis 3

    Für das Wort nehmen Sie im Absatz einen ternären Ausdruck: {count === 1 ? 'message' : 'messages'}.

Eine Lösung zeigen

Ein möglicher Lösungsweg. Ihrer kann anders aussehen und trotzdem alle Prüfungen bestehen.

export function Inbox({ count }) {
  return (
    <div>
      <h2>Inbox</h2>
      {count > 0 && <p>You have {count} new {count === 1 ? 'message' : 'messages'}</p>}
    </div>
  );
}

export default function App() {
  return (
    <>
      <Inbox count={3} />
      <Inbox count={1} />
      <Inbox count={0} />
    </>
  );
}
Auf dem eigenen Computer ausführen

Installieren Sie React 19.3 oder neuer. Speichern Sie diese Dateien in einem Ordner, öffnen Sie dort ein Terminal und führen Sie die Befehle unten aus.

main.jsx

// TODO: with 0 messages, show nothing below the heading (no stray 0).
// With 1 message, say "message"; otherwise "messages".
export function Inbox({ count }) {
  return (
    <div>
      <h2>Inbox</h2>
      {count && <p>You have {count} new messages</p>}
    </div>
  );
}

export default function App() {
  return (
    <>
      <Inbox count={3} />
      <Inbox count={1} />
      <Inbox count={0} />
    </>
  );
}

main.test.jsx

import {test} from 'node:test';
import assert from 'node:assert/strict';
import {render, screen} from '@testing-library/react';
import {Inbox} from './main.jsx';

test('3 Nachrichten: You have 3 new messages', () => {
  render(<Inbox count={3} />);
  const line = screen.getByText(/^You have/).textContent;
  assert.equal(line, 'You have 3 new messages', 'die Zeile lautet ' + JSON.stringify(line));
});

test('1 Nachricht: You have 1 new message', () => {
  render(<Inbox count={1} />);
  const line = screen.getByText(/^You have/).textContent;
  assert.equal(line, 'You have 1 new message', 'die Zeile lautet ' + JSON.stringify(line));
});

test('0 Nachrichten: nur die Überschrift, keine verirrte 0', () => {
  const {container} = render(<Inbox count={0} />);
  assert.equal(container.textContent, 'Inbox', 'die Inbox lautet ' + JSON.stringify(container.textContent));
});

Legen Sie main.jsx in einem Vite-React-Projekt (npm create vite@latest, Vorlage react) als App.jsx in src/ ab und starten Sie es mit npm run dev. React rendert es dort wie hier in <StrictMode>.

Programm ausführen:

npm run dev

Für die Prüfungen gibt es noch keinen Befehl auf Ihrem Computer. Sie stehen in main.test.jsx, geschrieben mit node:test und React Testing Library.

Häufige Fehler

Eine if-Anweisung in JSX-Klammern schreiben

function Item({ name, isPacked }) {
  return (
    <li className="item">
      {if (isPacked) { name + ' ✅' }}
    </li>
  );
}

export default function PackingList() {
  return (
    <ul>
      <Item name="Tent" isPacked={true} />
    </ul>
  );
}

Was React ausgibt

error TS1109: Expression expected.

Warum, und die Lösung

Geschweifte Klammern in JSX nehmen einen Ausdruck, und if ist eine Anweisung, deshalb bricht die JSX-Umwandlung ab, und nichts läuft. Die ganze Zeile beginnt mit der Position, main.jsx(4,8), und es folgt ein zweiter Fehler, TS1381. Verwenden Sie in den Klammern den ternären Operator, {isPacked ? name + ' ✅' : name}, oder setzen Sie das if vor das return.

Den Sonst-Teil eines ternären Ausdrucks weglassen

function Item({ name, isPacked }) {
  return <li className="item">{name} {isPacked ? '✅'}</li>;
}

export default function PackingList() {
  return (
    <ul>
      <Item name="Tent" isPacked={true} />
    </ul>
  );
}

Was React ausgibt

error TS1005: ':' expected.

Warum, und die Lösung

Der Bedingungsoperator hat immer drei Teile: Bedingung ? dann : sonst. Die ganze Zeile beginnt mit main.jsx(2,53). Ergänzen Sie den Sonst-Wert, {isPacked ? '✅' : ''}, oder nehmen Sie, wenn sonst nichts zu zeigen ist, stattdessen &&: {isPacked && '✅'}.

Die JSX-Variable mit const deklarieren

function Item({ name, isPacked }) {
  const content = name;
  if (isPacked) {
    content = name + ' ✅';
  }
  return <li className="item">{content}</li>;
}

export default function PackingList() {
  return (
    <ul>
      <Item name="Tent" isPacked={true} />
    </ul>
  );
}

Was React ausgibt

TypeError: Assignment to constant variable.

Warum, und die Lösung

Eine const lässt sich nicht neu zuweisen, deshalb wirft das if, während Tent rendert, und der Lauf gibt Uncaught TypeError aus (Formulierung von Chrome und Node.js; Firefox und Safari formulieren es anders). Deklarieren Sie die Variable mit let, wie react.dev es tut: let content = name;.

React im Browser: React 19.3.0 (Entwicklungs-Build) und React Testing Library, MIT, von dieser Website ausgeliefert; JSX übersetzt TypeScript 6.0.3, Apache-2.0. Lizenz und Quellcode

Abschlussquiz

5 Fragen, ohne Hinweise. Ab 80 % ist die Lektion abgeschlossen.

Erledigen Sie zuerst alle Aufgaben oben, um das Abschlussquiz freizuschalten.

Problem melden

Etwas ist falsch oder unklar? Beschreiben Sie es kurz, dann wird es geprüft und korrigiert.

#

Mindestens 20 Zeichen.

Nur, wenn Sie eine Antwort wünschen.

Kernideen

Bedingungen sind ganz normales JavaScript

React hat keine eigene Syntax für Bedingungen: Sie verwenden JavaScript. Eine Komponente kann ein Prop mit if prüfen und anderes JSX zurückgeben: if (isPacked) { return <li>{name} ✅</li>; } return <li>{name}</li>;. Um gar nichts zu rendern, geben Sie null zurück. react.dev merkt an, dass das nicht üblich ist, weil es überraschen kann, wer die Komponente rendert; meist entscheiden die Eltern, ob sie sie einbinden. Eine if-Anweisung kann nicht in die JSX-Klammern: Klammern nehmen einen Ausdruck, if ist eine Anweisung, deshalb bricht die JSX-Umwandlung ab.

Das ternäre ? : wählt im JSX

Wenn sich zwei Zweige nur in einem kleinen Teil unterscheiden, hält der Bedingungsoperator das JSX an einem Ort: <li>{isPacked ? name + ' ✅' : name}</li>. Lesen Sie es so: wenn isPacked, dann dies, sonst das. Jede Seite kann auch JSX sein: {isPacked ? <del>{name}</del> : name}. Die if-Fassung und der ternäre Operator beschreiben dasselbe Ergebnis; JSX-Elemente sind nur Beschreibungen. Ein ternärer Ausdruck braucht immer beide Teile: Ohne das : und den Sonst-Wert lässt sich der Code nicht übersetzen. Bei tieferer Verschachtelung rät react.dev, Kindkomponenten herauszuziehen.

&& nimmt auf oder lässt weg, let sammelt

{isPacked && '✅'} zeigt das Häkchen, wenn isPacked true ist, und nichts, wenn es false ist: React behandelt false, null und undefined als Löcher und rendert nichts. Setzen Sie aber nie eine Zahl links vor &&: Mit count = 0 rendert {count && <p>New</p>} eine 0. Schreiben Sie einen Boolean, count > 0 &&. Wenn die Kurzformen stören, nehmen Sie eine Variable: let content = name; if (isPacked) { content = <del>{name}</del>; } und dann {content} im JSX. Das braucht let, denn const lässt sich nicht neu zuweisen.

Quellen

Zuletzt geprüft am 5. Oktober 2026