Zum Inhalt springen
React Anfänger 20 min

Bedingtes Rendern

Lerne alle Techniken für bedingtes Rendern in React. Zeige verschiedene UI-Zustände abhängig von Bedingungen an.

Aktualisiert:

Bedingtes Rendern

In React musst du haeufig verschiedene Inhalte anzeigen, je nachdem welcher Zustand gerade aktiv ist. Ist der User eingeloggt? Sind Daten geladen? Gibt es Fehler? Bedingtes Rendern ist die Antwort.

if/else mit fruehen Returns

Das einfachste Pattern – pruefe eine Bedingung und gib verschiedenes JSX zurueck:

function UserGreeting({ isLoggedIn }) {
  if (isLoggedIn) {
    return <h1>Willkommen zurueck!</h1>;
  }

  return <h1>Bitte melde dich an.</h1>;
}

Mehrere Zustaende

function DataDisplay({ status, data, error }) {
  if (status === 'loading') {
    return <p>Laden...</p>;
  }

  if (status === 'error') {
    return <p style={{ color: 'red' }}>Fehler: {error}</p>;
  }

  if (!data || data.length === 0) {
    return <p>Keine Daten vorhanden.</p>;
  }

  return (
    <ul>
      {data.map(item => (
        <li key={item.id}>{item.name}</li>
      ))}
    </ul>
  );
}

Ternary Operator

Ideal fuer einfache Entweder-Oder-Entscheidungen innerhalb von JSX:

function LoginButton({ isLoggedIn, onLogin, onLogout }) {
  return (
    <button onClick={isLoggedIn ? onLogout : onLogin}>
      {isLoggedIn ? 'Abmelden' : 'Anmelden'}
    </button>
  );
}

Verschiedene Komponenten anzeigen

function App({ user }) {
  return (
    <div>
      <Header />
      {user ? <Dashboard user={user} /> : <LoginForm />}
      <Footer />
    </div>
  );
}

Verschiedene Styles anwenden

function StatusBadge({ status }) {
  return (
    <span style={{
      padding: '4px 12px',
      borderRadius: '12px',
      color: 'white',
      backgroundColor: status === 'active' ? '#27ae60' :
                        status === 'pending' ? '#f39c12' :
                        '#e74c3c'
    }}>
      {status === 'active' ? 'Aktiv' :
       status === 'pending' ? 'Ausstehend' :
       'Inaktiv'}
    </span>
  );
}

Logischer AND-Operator (&&)

Zeige etwas an nur wenn eine Bedingung wahr ist:

function Notifications({ count }) {
  return (
    <div>
      <h1>Dashboard</h1>
      {count > 0 && (
        <div style={{
          padding: '0.5rem 1rem',
          background: '#e74c3c',
          color: 'white',
          borderRadius: '8px'
        }}>
          Du hast {count} neue Benachrichtigung{count !== 1 ? 'en' : ''}!
        </div>
      )}
    </div>
  );
}

Vorsicht mit Zahlen!

// BUG: Wenn count = 0, wird "0" gerendert!
{count && <span>{count} Nachrichten</span>}

// RICHTIG: Expliziter Vergleich
{count > 0 && <span>{count} Nachrichten</span>}

// ALTERNATIVE: Boolean-Konvertierung
{!!count && <span>{count} Nachrichten</span>}

Logischer OR-Operator (||)

Zeige einen Fallback an, wenn ein Wert falsy ist:

function UserProfile({ user }) {
  return (
    <div>
      <img src={user.avatar || '/default-avatar.png'} alt="Avatar" />
      <h2>{user.name || 'Unbekannter Benutzer'}</h2>
      <p>{user.bio || 'Keine Biografie vorhanden.'}</p>
    </div>
  );
}

Nullish Coalescing (??)

Aehnlich wie ||, aber nur fuer null und undefined:

function Settings({ fontSize, showHeader }) {
  // ?? unterscheidet zwischen "kein Wert" und "false/0"
  const size = fontSize ?? 16;        // 0 wuerde beibehalten
  const header = showHeader ?? true;   // false wuerde beibehalten

  return (
    <div style={{ fontSize: size }}>
      {header && <h1>Einstellungen</h1>}
      <p>Schriftgroesse: {size}px</p>
    </div>
  );
}

Switch/Object-Pattern

Fuer viele Zustaende nutze ein Objekt statt verschachtelter Ternaries:

function Icon({ type }) {
  const icons = {
    success: '✓',
    warning: '⚠',
    error: '✗',
    info: 'ℹ'
  };

  return <span>{icons[type] || icons.info}</span>;
}

// Auch fuer Komponenten:
function Page({ currentPage }) {
  const pages = {
    home: <HomePage />,
    about: <AboutPage />,
    contact: <ContactPage />,
    settings: <SettingsPage />
  };

  return pages[currentPage] || <NotFoundPage />;
}

Elemente ein-/ausblenden

Mit CSS (Element bleibt im DOM)

function Collapsible({ title, children }) {
  const [isOpen, setIsOpen] = useState(false);

  return (
    <div>
      <button onClick={() => setIsOpen(!isOpen)}>
        {title} {isOpen ? '▼' : '▶'}
      </button>
      <div style={{ display: isOpen ? 'block' : 'none' }}>
        {children}
      </div>
    </div>
  );
}

Mit bedingtem Rendern (Element wird entfernt/hinzugefuegt)

function Collapsible({ title, children }) {
  const [isOpen, setIsOpen] = useState(false);

  return (
    <div>
      <button onClick={() => setIsOpen(!isOpen)}>
        {title} {isOpen ? '▼' : '▶'}
      </button>
      {isOpen && <div>{children}</div>}
    </div>
  );
}
MethodeVorteilNachteil
display: noneState bleibt erhaltenElement im DOM
Bedingtes RendernSauberes DOMState geht verloren

Praktisches Beispiel: Tab-Navigation

function Tabs() {
  const [activeTab, setActiveTab] = useState('profile');

  const tabs = [
    { id: 'profile', label: 'Profil' },
    { id: 'settings', label: 'Einstellungen' },
    { id: 'notifications', label: 'Benachrichtigungen' }
  ];

  return (
    <div>
      <div style={{ display: 'flex', borderBottom: '2px solid #eee' }}>
        {tabs.map(tab => (
          <button
            key={tab.id}
            onClick={() => setActiveTab(tab.id)}
            style={{
              padding: '0.75rem 1.5rem',
              border: 'none',
              background: 'none',
              cursor: 'pointer',
              borderBottom: activeTab === tab.id ? '2px solid #3498db' : '2px solid transparent',
              color: activeTab === tab.id ? '#3498db' : '#666',
              fontWeight: activeTab === tab.id ? 'bold' : 'normal'
            }}
          >
            {tab.label}
          </button>
        ))}
      </div>

      <div style={{ padding: '1.5rem' }}>
        {activeTab === 'profile' && (
          <div>
            <h2>Profil</h2>
            <p>Hier kannst du dein Profil bearbeiten.</p>
          </div>
        )}
        {activeTab === 'settings' && (
          <div>
            <h2>Einstellungen</h2>
            <p>Passe deine Einstellungen an.</p>
          </div>
        )}
        {activeTab === 'notifications' && (
          <div>
            <h2>Benachrichtigungen</h2>
            <p>Verwalte deine Benachrichtigungen.</p>
          </div>
        )}
      </div>
    </div>
  );
}

Uebungen

  1. Baue eine Login/Logout-Ansicht, die zwischen zwei Zustaenden wechselt
  2. Erstelle einen mehrstufigen Wizard, der je nach Schritt verschiedene Inhalte zeigt
  3. Baue eine Benachrichtigungs-Komponente mit den Varianten success, warning und error

Was kommt als Naechstes?

Du beherrschst jetzt bedingtes Rendern. Im naechsten Kapitel lernst du den useEffect Hook – damit kannst du Seiteneffekte wie API-Aufrufe, Timer und DOM-Manipulationen in deinen Komponenten ausfuehren.

Zusammenfassung

  • Fruehe Returns mit if/else fuer verschiedene Zustaende einer ganzen Komponente
  • Ternary Operator fuer Entweder-Oder-Entscheidungen im JSX
  • AND-Operator (&&) fuer bedingtes Anzeigen einzelner Elemente
  • OR-Operator (||) und Nullish Coalescing (??) fuer Fallback-Werte
  • Object-Pattern statt verschachtelter Ternaries bei vielen Zustaenden
  • Beachte den Unterschied zwischen CSS-Ausblenden und bedingtem Rendern

Pro-Tipp: Wenn du dich dabei ertappst, mehr als 2-3 verschachtelte Ternary-Operatoren zu verwenden, ist es Zeit fuer eine Umstrukturierung. Nutze stattdessen fruehe Returns, das Object-Pattern oder lagere die Logik in eigene Komponenten aus!

Zurück zum React Kurs