React State & Props

6 Kernkonzepte
Die wichtigsten React-Konzepte für State und Props: useState · Lifting State · Immutabilität · Callback Props · Props Drilling · Context API State und Props sind das Herzstück von React. Diese Cheatsheet behandelt die Verwaltung von Daten in Komponenten, den Datenfluss zwischen Komponenten und die Lösung von Herausforderungen wie Props Drilling.

useState – State in funktionalen Komponenten

useState · setter · Lazy Initialization
const [count, setCount] = useState(0); const [user, setUser] = useState({ name: "", email: "" }); const [items, setItems] = useState(() => expensiveComputation()); // Lazy

useState ist der grundlegende Hook für die Verwaltung von State in funktionalen Komponenten. Er gibt den aktuellen Wert und eine Setter-Funktion zurück, die das erneute Rendern auslöst.

Wichtige useState-Muster

Muster Beschreibung Beispiel
Einfach Primitive Werte const [count, setCount] = useState(0)
Objekt Mehrere zusammengehörige Werte const [user, setUser] = useState({ name: '', age: 0 })
Array Listen von Elementen const [items, setItems] = useState([])
Lazy Initialization Initialwert wird erst bei Bedarf berechnet useState(() => expensiveComputation())
Funktionale Aktualisierung Update basierend auf vorherigem Wert setCount(prev => prev + 1)
Beispiele
// useState mit Objekt
const [form, setForm] = useState({ username: "", password: "" });
const handleChange = (e) => {
setForm({ ...form, [e.target.name]: e.target.value });
};
// useState mit Array (Hinzufügen/Entfernen)
const [todos, setTodos] = useState([]);
// Hinzufügen
setTodos([...todos, { id: Date.now(), text: "Neuer Todo" }]);
// Entfernen
setTodos(todos.filter((todo) => todo.id !== id));
// Funktionale Aktualisierung (sichere Variante)
setCount((prevCount) => {
return prevCount + 1;
});
// Lazy Initialization (teure Berechnungen)
const [data, setData] = useState(() => {
// Wird nur einmal beim ersten Rendern ausgeführt
return expensiveInitialization();
});
Tipp: Verwenden Sie die funktionale Aktualisierung, wenn der neue State vom vorherigen State abhängt – das verhindert Race Conditions bei asynchronen Updates und ist besonders bei häufigen Updates wichtig.

Lifting State – State nach oben heben

Shared State · Single Source of Truth
// Parent-Komponente (Shared State) function Parent() { const [count, setCount] = useState(0); return ( <> <ChildA count={ count } onIncrement={() => setCount(c => c + 1)} /> <ChildB count={ count } /> </> ); }

Lifting State bedeutet, dass State von einer Kindkomponente in die nächste gemeinsame Elternkomponente verschoben wird. So können mehrere Komponenten denselben State nutzen und aktualisieren.

Beispiele
// Parent-Komponente mit gemeinsamem State
function App() {
const [items, setItems] = useState([]);
const addItem = (text) => {
setItems([...items, { id: Date.now(), text }]);
};
const removeItem = (id) => {
setItems(items.filter((item) => item.id !== id));
};
return (
<div>
<TodoInput onAdd={ addItem } />
<TodoList items={ items } onRemove={ removeItem } />
</div>
);
}
// Child-Komponente: Empfängt State und Callback
function TodoList({ items, onRemove }) {
return (
<ul>
{ items.map((item) => (
<li key={ item.id }>
{ item.text }
<button onClick={() => onRemove(item.id)}>Löschen</button>
</li>
))
</ul>
);
}
Tipp: Lifting State ist die Grundlage für "Single Source of Truth" – eine zentrale Datenquelle für alle Komponenten, die auf denselben State zugreifen müssen.

Immutabilität – State nicht direkt verändern

Spread · map · filter · immer
// ❌ Falsch (direkte Mutation) state.count = state.count + 1; // ✅ Richtig (neues Objekt) setState({ ...state, count: state.count + 1 });

Immutabilität bedeutet, dass State niemals direkt verändert wird. Stattdessen wird ein neuer Wert erstellt und mit der Setter-Funktion gesetzt. Das ist essenziell für korrektes Rendering und Debugging.

Immutable Update Patterns

Datentyp Pattern Beispiel
Primitive Einfach zuweisen setCount(count + 1)
Objekt Spread-Operator setUser({ ...user, age: user.age + 1 })
Array (Hinzufügen) Spread oder concat setItems([...items, newItem])
Array (Entfernen) filter setItems(items.filter(i => i.id !== id))
Array (Aktualisieren) map setItems(items.map(i => i.id === id ? { ...i, done: true } : i))
Verschachtelt Mehrere Spreads setState({ ...state, user: { ...state.user, age: 30 } })
Beispiele
// Objekt-Update
const [user, setUser] = useState({ name: "Anna", age: 30 });
// Alter aktualisieren
setUser({ ...user, age: user.age + 1 });
// Array-Element aktualisieren
const [items, setItems] = useState([{ id: 1, done: false }]);
setItems(items.map((item) =>
item.id === 1 ? { ...item, done: true } : item
));
// Verschachteltes Objekt
const [state, setState] = useState({
user: { name: "Anna", address: { city: "Berlin", zip: 10115 } }
});
// Stadt aktualisieren
setState({
...state,
user: {
...state.user,
address: {
...state.user.address,
city: "München"
}
}
});
Tipp: Für tief verschachtelte State-Updates empfiehlt sich die Bibliothek immer (siehe useImmer von use-immer), die eine mutierende Syntax erlaubt und trotzdem immutable Updates erzeugt.

Callback Props – Funktionen als Props

onClick · onChange · onEvent
// Elternkomponente function Parent() { const handleClick = () => { /* ... */ }; return <Child onClick={ handleClick } />; } // Kindkomponente function Child({ onClick }) { return <button onClick={ onClick }>Klick</button>; }

Callback Props sind Funktionen, die von einer Elternkomponente an eine Kindkomponente übergeben werden. Die Kindkomponente kann diese Funktion aufrufen, um Daten oder Events an die Elternkomponente zurückzugeben.

Beispiele
// Counter mit Callback
function Counter() {
const [count, setCount] = useState(0);
const handleIncrement = () => {
setCount(count + 1);
};
return (
<div>
<span>Count: { count }</span>
<Button onClick={ handleIncrement } label="+" />
</div>
);
}
// Kindkomponente mit Callback
function Button({ onClick, label }) {
return <button onClick={ onClick }>{ label }</button>;
}
// Callback mit Daten vom Kind
function Parent() {
const handleData = (data) => {
console.log("Daten vom Kind:", data);
};
return <Child onSubmit={ handleData } />;
}
function Child({ onSubmit }) {
const handleClick = () => {
onSubmit({ message: "Hallo von Child" });
};
return <button onClick={ handleClick }>Senden</button>;
}
Tipp: Benennen Sie Callback-Props immer mit on als Präfix (z.B. onClick, onChange, onSubmit) – das entspricht dem React-Standard und macht den Code lesbarer.

Props Drilling & Context – Daten über Ebenen weitergeben

Context API · Provider · useContext
// Context erstellen const ThemeContext = createContext(); // Provider <ThemeContext.Provider value={ "dark" }> <App /> </ThemeContext.Provider> // In tiefer Komponente const theme = useContext(ThemeContext);

Props Drilling ist das Problem, dass Props über mehrere Komponentenebenen durchgereicht werden müssen. Die Context API bietet eine elegante Lösung, um Daten ohne Prop Drilling zu teilen.

Beispiele
// Context für Benutzerdaten
const UserContext = createContext(null);
// App mit Provider
function App() {
const [user, setUser] = useState({ name: "Anna" });
return (
<UserContext.Provider value={ user }>
<Dashboard />
</UserContext.Provider>
);
}
// Dashboard (kein Prop-Drill)
function Dashboard() {
return <Profile />;
}
// Profile (Context konsumieren)
function Profile() {
const user = useContext(UserContext);
return <p>Benutzer: { user?.name }</p>;
}
// Context mit Updater-Funktion
const AppContext = createContext(null);
function App() {
const [theme, setTheme] = useState("light");
const value = { theme, setTheme };
return (
<AppContext.Provider value={ value }>
<ThemedComponent />
</AppContext.Provider>
);
}
function ThemedComponent() {
const { theme, setTheme } = useContext(AppContext);
return (
<div className={ theme }>
<button onClick={() => setTheme(theme === "light" ? "dark" : "light")}>
Thema wechseln
</button>
</div>
);
}
Tipp: Context ist ideal für globale Daten wie Theme, Sprache, Benutzerinformationen oder Konfiguration. Für häufige Updates (wie Formulardaten) ist Context nicht immer die beste Wahl – hier können State-Management-Bibliotheken helfen.

State & Props im Überblick

Props Schreibgeschützte Daten
Von Eltern an Kind
State Veränderliche Daten
useState, useReducer
Lifting State nach oben heben
Shared State
Immutability Nicht direkt mutieren
Spread, map, filter
Callback Props Funktionen als Props
onClick, onChange
Context Globale Daten
Props Drilling vermeiden

Quick Summary

useState
State verwalten
Lifting
State nach oben
Immutability
Nicht mutieren
Callback
Funktionen als Props
Prop Drilling
Problem
Context
Lösung
const [state, setState] = useState(0) · setState({ ...state, key: value }) · const context = useContext(AppContext)