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

EigenschaftStateProps
Wer besitzt die Daten?Die Komponente selbstDie Eltern-Komponente
Wer darf sie ändern?Nur die besitzende KomponenteNiemand (read-only innerhalb Kind)
Reicht weiter nach unten?Optional, über PropsJa, von Eltern zu Kind
InitialisierunguseState(initialValue)Beim JSX-Aufruf gesetzt
AnwendungVeränderliche, lokale WerteDaten, die von außen kommen
Auslöser für Re-RendersetState-AufrufGeänderte Prop vom Eltern-Render

Kurz: Props kommen von außen rein, State entsteht innen.

Beispiel-Komponente mit beidem

TypeScript Greeting.jsx
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>
    );
}
  • name ist eine Prop – kommt von außen, wird im Kind nicht verändert.
  • greeted ist 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.

TypeScript − Niemals direkt eine Prop verändern
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:

  1. Bleibt der Wert über die Zeit gleich? -> Konstante. Weder State noch Prop, sondern eine normale Variable oder Konstante.
  2. Bekommt die Komponente den Wert von außen? -> Prop.
  3. 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:

TypeScript + Abgeleitete Werte einfach berechnen
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:

TypeScript Parent + Child
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.

TypeScript − Anti-Pattern
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.
TypeScript + key zwingt State-Reset
// 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.

Weiterführende Ressourcen

Externe Quellen

/ Weiter

Zurück zu State

Zur Übersicht