Zwei der wichtigsten Konzepte in React – State und Props – werden gerne verwechselt. Beide halten Daten, beide lösen Re-Renders aus, beide werden in Komponenten genutzt. Trotzdem haben sie unterschiedliche Aufgaben und unterschiedliche Eigenschaften. Dieser Artikel erklärt den Unterschied, zeigt typische Verwechslungen und gibt klare Regeln, wann Daten in den State gehören und wann sie als Prop gereicht werden sollten.
Die Kernunterschiede in einem Bild
| Eigenschaft | State | Props |
|---|---|---|
| Wer besitzt die Daten? | Die Komponente selbst | Die Eltern-Komponente |
| Wer darf sie ändern? | Nur die besitzende Komponente | Niemand (read-only innerhalb Kind) |
| Reicht weiter nach unten? | Optional, über Props | Ja, von Eltern zu Kind |
| Initialisierung | useState(initialValue) | Beim JSX-Aufruf gesetzt |
| Anwendung | Veränderliche, lokale Werte | Daten, die von außen kommen |
| Auslöser für Re-Render | setState-Aufruf | Geänderte Prop vom Eltern-Render |
Kurz: Props kommen von außen rein, State entsteht innen.
Beispiel-Komponente mit beidem
import { useState } from 'react';
function Greeting({ name }) {
const [greeted, setGreeted] = useState(false);
return (
<div>
<h1>Hallo, {name}!</h1>
{!greeted && (
<button onClick={() => setGreeted(true)}>
Begrüßung bestätigen
</button>
)}
{greeted && <p>Schön, dich zu sehen.</p>}
</div>
);
}nameist eine Prop – kommt von außen, wird im Kind nicht verändert.greetedist State – gehört zur Komponente, wird per Klick verändert.
Props sind read-only
Eine Komponente darf ihre Props nicht direkt verändern. Das ist eine harte Regel von React – Verstöße führen zu schwer auffindbaren Bugs, weil die Eltern-Komponente die Daten weiter besitzt und in einem späteren Render möglicherweise einen anderen Wert erwartet.
function Counter({ count }) {
count++; // − Prop wird mutiert
return <p>{count}</p>;
}Soll der Wert sich ändern können, muss er in den State (entweder lokal oder im Eltern-Component, der die Prop reicht). Mehr dazu unter State Lifting.
Drei Faustregeln zur Entscheidung
Wenn unklar ist, ob ein Wert State oder Prop sein soll, frage in dieser Reihenfolge:
- Bleibt der Wert über die Zeit gleich? -> Konstante. Weder State noch Prop, sondern eine normale Variable oder Konstante.
- Bekommt die Komponente den Wert von außen? -> Prop.
- Kann sich der Wert über die Zeit ändern, und keine andere Komponente besitzt ihn? -> State.
Wenn der Wert sich aus anderen Werten berechnen lässt, gehört er weder in State noch in Props – er wird beim Rendern abgeleitet:
function Cart({ items }) {
const total = items.reduce((sum, item) => sum + item.price, 0);
return <p>Gesamt: {total} €</p>;
}total darf weder State noch Prop sein – es ist eine reine Funktion von items.
State und Props zusammen
Häufig leitet ein Eltern-Komponente seinen State an Kinder weiter. Aus Sicht des Eltern ist es State, aus Sicht des Kindes ist es eine Prop. Das ist der Kern des einseitigen Datenflusses:
function Counter() {
const [count, setCount] = useState(0); // State im Parent
return (
<div>
<Display value={count} />
<button onClick={() => setCount(count + 1)}>+1</button>
</div>
);
}
function Display({ value }) {
// Aus Sicht von Display ist value eine Prop
return <p>{value}</p>;
}Display weiß nicht, woher der Wert kommt – ob aus State, aus einem Context oder aus einem Server-Request. Genau das macht es wiederverwendbar.
Anti-Pattern: Prop in State spiegeln
Ein häufiger Fehler: Eine Prop wird beim Mounten in einen State kopiert, um sie „bearbeitbar" zu machen.
function Form({ initialName }) {
const [name, setName] = useState(initialName);
// Problem: Wenn sich initialName ändert, bleibt name auf altem Wert.
return <input value={name} onChange={(e) => setName(e.target.value)} />;
}Das funktioniert für den ersten Render – aber wenn der Eltern-Komponent eine neue initialName-Prop liefert, bleibt der State auf dem alten Wert hängen. Bessere Optionen:
- Prop direkt verwenden, falls keine Bearbeitung nötig ist.
- Den State im Eltern-Komponent halten und Setter als Prop reichen.
- Per
key-Prop den State bewusst zurücksetzen, wenn die Identität wechselt.
// Wenn userId wechselt, wird der gesamte State von Form weggeworfen
<Form key={userId} initialName={userName} />Was passiert beim Re-Render?
- State-Update (
setX(...)) führt dazu, dass die Komponente und ihre Kinder neu gerendert werden. - Prop-Änderung führt dazu, dass die empfangende Komponente neu gerendert wird.
In beiden Fällen baut React den virtuellen Baum neu auf und vergleicht ihn mit dem alten. Das heißt: Sobald State irgendwo oben wechselt, rendern alle abhängigen Komponenten – das ist das normale, gewünschte Verhalten. Performance-Stellschrauben dafür: React.memo, useMemo, useCallback.