Props (Properties) sind der Mechanismus, mit dem eine React-Komponente Daten von ihrem Eltern-Element bekommt. Außen werden sie als Attribute geschrieben (<Greeter name="Anna" />), innen kommen sie als Parameter der Funktion an. Props machen Komponenten wiederverwendbar — dieselbe Card rendert mal mit „Hallo", mal mit „Profil" als Inhalt. Sie sind read-only: eine Komponente darf ihre eigenen Props nicht verändern. Dieser Artikel zeigt den Grundmechanismus, Destructuring im Parameter, Default-Werte, komplexe Datentypen und die spezielle children-Prop.
Einführung in Props
Props werden als Attribute im JSX-Aufruf gesetzt und als Objekt-Parameter der Komponenten-Funktion empfangen. Per Konvention heißt dieser Parameter props.
const Greeter = (props) => {
return <p>Hi, {props.name}</p>;
};
export default Greeter;Verwendung:
<Greeter name="Max" />
<Greeter name="Anna" />Beide Aufrufe nutzen dieselbe Komponente — mit unterschiedlicher Konfiguration. Genau dieses Pattern macht Komponenten so mächtig.
Destructuring im Parameter
In der Praxis wird der props-Parameter fast immer direkt destructured — die einzelnen Eigenschaften werden ausgepackt und stehen als Variablen zur Verfügung.
const User = ({ name, age, isActive }) => {
return (
<div className="user-wrapper">
<div className="user-name">{name}</div>
<div className="user-age">{age}</div>
<div className="user-status">
{isActive ? 'Active' : 'Inactive'}
</div>
</div>
);
};
export default User;Verwendung wie üblich:
<User
name="Max"
age={30}
isActive={true}
/>Zwei Schreibweisen, gleicher Effekt — Destructuring im Parameter ist die idiomatische moderne Form.
Default-Werte für Props
Mit dem =-Operator beim Destructuring lassen sich Default-Werte für fehlende Props angeben. Wenn die Prop nicht übergeben wird (oder explizit undefined ist), greift der Default.
const CustomButton = ({ text = 'Speichern', type = 'default' }) => {
return (
<button className={`btn btn-${type}`}>{text}</button>
);
};
export default CustomButton;Vier Aufruf-Varianten, alle gültig:
<CustomButton /> // alle Defaults
<CustomButton type="primary" /> // text default, type override
<CustomButton text="Senden" /> // type default, text override
<CustomButton text="Weiter" type="secondary" /> // beide overrideWichtig: nur undefined löst den Default aus, nicht null, nicht 0, nicht ''. Das ist konsistent mit JavaScript-Default-Parametern.
Komplexe Datentypen — Objekte und Arrays
Props können beliebige JavaScript-Werte sein: Strings, Numbers, Booleans, Objects, Arrays, Funktionen, sogar JSX-Elemente. Komplexe Daten werden in {...} gesetzt (außer Strings als Attribut-Wert, die in "...").
const SampleProduct = ({ productData }) => {
return (
<div className="product-data">
<ul>
<li><strong>Artikelname:</strong> {productData.name}</li>
<li><strong>Preis:</strong> {productData.price}</li>
<li><strong>Art-Nr.:</strong> {productData.articleNumber}</li>
<li>
<strong>Auf Lager:</strong>
{productData.inStock ? 'Ja' : 'Nein'}
</li>
</ul>
</div>
);
};
export default SampleProduct;const productInfos = {
name: 'Laptop',
price: 1299.99,
articleNumber: '87263',
inStock: true,
};
export default function App() {
return <SampleProduct productData={productInfos} />;
}Statt ein großes Objekt zu übergeben, kann man auch die einzelnen Properties als separate Props weitergeben — beides idiomatisch. Bei tieferer Verschachtelung wird das Objekt-Argument schnell unhandlich; einzelne Props sind dann lesbarer.
Funktionen als Props — Callbacks
Eine der häufigsten Anwendungen: einer Kind-Komponente eine Callback-Funktion als Prop übergeben, damit sie auf Events nach oben kommunizieren kann.
const LikeButton = ({ onLike }) => {
return <button onClick={onLike}>Gefällt mir</button>;
};
const Post = () => {
const handleLike = () => console.log('Geliked!');
return <LikeButton onLike={handleLike} />;
};Naming-Konvention: Event-Handler-Props beginnen mit on (onClick, onChange, onLike). Innerhalb der Kind-Komponente heißt der Handler oft handle... (handleLike, handleSubmit).
children als spezielle Prop
children ist eine reservierte Prop. Sie wird nicht als Attribut geschrieben, sondern automatisch mit allem gefüllt, was zwischen den Komponenten-Tags steht.
const Card = ({ children }) => {
return <div className="card">{children}</div>;
};
const App = () => (
<Card>
<h2>Titel</h2>
<p>Inhalt</p>
</Card>
);Damit wird die Card zum generischen Container, der nicht weiß, was er rendert — er reicht den Inhalt nur durch und stylt den Rahmen. Das ist das Fundament von Komposition, dem wichtigsten Strukturprinzip in React.
Details und Patterns dazu im Artikel zu Children Prop.
Spread-Operator für Props
Wenn ein Object alle Props enthält, kann man sie mit Spread an die Komponente weiterreichen:
const userProps = { name: 'Anna', age: 30, isActive: true };
// Ohne Spread
<User name={userProps.name} age={userProps.age} isActive={userProps.isActive} />
// Mit Spread — kompakt, aber unspezifischer
<User {...userProps} />Praktisch beim Forwarding von Props (Wrapper-Komponente, die alle Props an die innere Komponente durchreicht). Vorsicht: Spread macht es schwer, auf einen Blick zu sehen, welche Props ankommen — gerade in TypeScript hilft das Compiler-Feedback.
TypeScript: Props typisieren
In TypeScript-Projekten definiert man explizit, welche Props eine Komponente erwartet. Das gibt Autocomplete, Type-Checks und vermeidet ganze Fehler-Klassen.
type UserCardProps = {
name: string;
age: number;
isActive?: boolean; // optional
onClick?: () => void;
};
const UserCard = ({ name, age, isActive = false, onClick }: UserCardProps) => {
return (
<div onClick={onClick}>
<h2>{name}</h2>
<p>Alter: {age}</p>
<p>Status: {isActive ? 'Aktiv' : 'Inaktiv'}</p>
</div>
);
};Das alte React.FC<Props>-Pattern ist heute nicht mehr empfohlen — die direkte Typisierung des Parameters ist klarer und vermeidet implizite children-Annahmen.
Häufige Stolperfallen
Props sind read-only — niemals direkt verändern.
props.name = 'X' ist ein Anti-Pattern. React erwartet, dass Props immutable sind. Bei Verstoß: Warnings in StrictMode, schwer auffindbare Bugs in Production. Wer Werte ändern muss, nutzt useState in der eigenen Komponente.
Default-Wert greift nur bei undefined, nicht bei null oder 0.
{ count = 5 } setzt 5 nur, wenn count nicht übergeben wurde oder explizit undefined ist. count={null} oder count={0} behalten ihren Wert. Konsistent mit JavaScript-Defaults.
Boolean-Prop kurz: isActive statt isActive={true}.
<User isActive /> ist äquivalent zu <User isActive={true} /> — wie in HTML. Kürzer und in vielen Codebases die bevorzugte Form für truthy-Booleans.
Spread mit unbekannten Props endet im DOM.
<div {...props} /> reicht ALLES weiter an das div — auch Props, die nicht in HTML existieren. React warnt darüber in Dev-Mode (Unknown prop ...). Lösung: vor dem Spread mit Destructuring filtern oder TypeScript für klare Typen nutzen.
Props-Drilling: tief verschachtelte Prop-Weitergabe wird schmerzhaft.
Wenn eine Prop durch 4-5 Komponenten durchgereicht wird, ohne dass die Zwischenkomponenten sie nutzen, ist das ein Code-Smell. Lösungen: Context API, Component-Composition, oder State-Management-Libraries (Redux, Zustand).
children-Prop kann nicht umbenannt werden.
children ist reserviert — React befüllt automatisch genau diesen Property-Namen mit dem Inhalt zwischen den Tags. Andere Namen funktionieren nicht; wer mehrere „Slots" braucht, übergibt sie als separate Props (z.B. header, footer) statt children.
Objekt- und Array-Props erzeugen neue Referenzen bei jedem Render.
<Child config={{ mode: 'A' }} /> erzeugt bei jedem Render ein neues Objekt — auch wenn der Inhalt gleich ist. Bei React.memo-optimierten Kindern führt das zu unnötigen Re-Renders. Lösung: das Objekt aus der Komponente extrahieren oder mit useMemo stabil halten.
Spread kombiniert mit benannten Props — Reihenfolge zählt.
<Btn type="primary" {...rest} /> erlaubt es, dass rest.type die explizite Angabe überschreibt. Wer das vermeiden will: explizite Props NACH dem Spread setzen — <Btn {...rest} type="primary" />.
Weiterführende Ressourcen
Externe Quellen
- Passing Props to a Component – react.dev
- JavaScript in JSX with Curly Braces – react.dev
- TypeScript with React – react.dev