Bedingtes Rendern
Lerne alle Techniken für bedingtes Rendern in React. Zeige verschiedene UI-Zustände abhängig von Bedingungen an.
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>
);
}
| Methode | Vorteil | Nachteil |
|---|---|---|
display: none | State bleibt erhalten | Element im DOM |
| Bedingtes Rendern | Sauberes DOM | State 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
- Baue eine Login/Logout-Ansicht, die zwischen zwei Zustaenden wechselt
- Erstelle einen mehrstufigen Wizard, der je nach Schritt verschiedene Inhalte zeigt
- 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!