Das Render-Props-Pattern in React
Das Render-Props-Pattern
~12 Min. Lesezeit Zuletzt aktualisiert am 8. August 2026
Render Props sind das zweite große Pattern aus der Vor-Hooks-Ära zur Logik-Wiederverwendung – statt einer Komponente (wie beim HOC) wird eine FUNKTION als Prop übergeben, die React aufruft, um zu bestimmen, WAS gerendert wird.
Die Grundidee: eine Funktion statt JSX als Kind
<DatenLader render={(daten) => <Text>{daten}</Text>} />
// oder, verbreiteter: children SELBST ist die Funktion ("function as children")
<DatenLader>{(daten) => <Text>{daten}</Text>}</DatenLader>Der Name "Render Prop" bezieht sich auf JEDE Prop, deren Wert eine Funktion ist, die React Elemente zurückgibt – ob sie render heißt oder (der heute übliche Sonderfall) children selbst diese Funktion ist, ist reine Namenskonvention.
MouseTracker bauen: ein klassisches Lehrbeispiel
Wir bauen das klassische Render-Props-Lehrbeispiel – eine Komponente, die die Mausposition verfolgt und sie an eine beliebige Darstellung weiterreicht, OHNE selbst zu wissen, wie diese Darstellung aussieht:
import { useState, useEffect } from 'react';
function MouseTracker({ children }) {
const [position, setPosition] = useState({ x: 0, y: 0 });
useEffect(() => {
function handleMouseMove(event) {
setPosition({ x: event.clientX, y: event.clientY });
}
window.addEventListener('mousemove', handleMouseMove);
return () => window.removeEventListener('mousemove', handleMouseMove);
}, []);
return children(position);
}
export default MouseTracker;return children(position) ist der entscheidende Moment: statt {{children}} direkt zu rendern (wie bei jeder normalen Komponente mit Kindern), wird children hier als FUNKTION AUFGERUFEN, mit position als Argument. Der AUFRUFER entscheidet komplett selbst, was mit den Mauskoordinaten dargestellt wird.
Verwendung: dieselbe Logik, zwei völlig unterschiedliche Darstellungen
Nutzen wir MouseTracker zu Demonstrationszwecken auf der Startseite – zweimal hintereinander, mit UNTERSCHIEDLICHER Darstellung derselben zugrundeliegenden Logik:
import MouseTracker from '../components/MouseTracker';
// ... irgendwo im JSX, rein zu Demonstrationszwecken:
<MouseTracker>
{(position) => <p>Maus bei: {position.x}, {position.y}</p>}
</MouseTracker>
<MouseTracker>
{(position) => (
<div
style={{
position: 'fixed',
left: position.x,
top: position.y,
width: 10,
height: 10,
borderRadius: '50%',
backgroundColor: 'red',
pointerEvents: 'none',
}}
/>
)}
</MouseTracker>GENAU DIESELBE MouseTracker-Logik (Event-Listener, State, Cleanup) wird wiederverwendet – einmal als Text-Anzeige, einmal als ein der Maus folgender roter Punkt. MouseTracker selbst weiß NICHTS von Text oder Punkten, nur von Koordinaten.
Der moderne Vergleich: derselbe Anwendungsfall als Custom Hook
// Als Custom Hook statt Render Prop:
function useMousePosition() {
const [position, setPosition] = useState({ x: 0, y: 0 });
useEffect(() => {
function handleMouseMove(event) {
setPosition({ x: event.clientX, y: event.clientY });
}
window.addEventListener('mousemove', handleMouseMove);
return () => window.removeEventListener('mousemove', handleMouseMove);
}, []);
return position;
}
// Verwendung - deutlich weniger JSX-Verschachtelung:
function MeineKomponente() {
const position = useMousePosition();
return <p>Maus bei: {position.x}, {position.y}</p>;
}| Pattern | Eigenschaft |
|---|---|
| Render Props | Erzeugt eine zusätzliche Verschachtelungsebene im JSX ("Wrapper Hell" light) – aber funktioniert AUSSERHALB von Komponentenfunktionen nicht anders nutzbar, rein deklarativ im JSX-Baum sichtbar. |
| Custom Hooks | Keine JSX-Verschachtelung, direkter Werte-Zugriff – ABER kann nur innerhalb einer Funktionskomponente aufgerufen werden, nicht als eigenständiges, im JSX sichtbares Element. |
Achtung: Eine bekannte Falle bei Render Props: eine Inline-Funktion als children ({{(position) => ...}}) erzeugt bei JEDEM Render von MeineKomponente eine NEUE Funktionsreferenz – genau das Problem aus Kapitel 31 mit React.memo. Würde MouseTracker selbst mit memo() eingepackt, würde das NICHTS bringen, solange die Render-Prop-Funktion inline bleibt.
Tipp: Bibliotheken, die dieses Muster noch aktiv nutzen: <Formik> (ältere Versionen), react-motion, einige Charting-Bibliotheken (D3-Wrapper). Für NEUEN eigenen Code ist ein Custom Hook heute fast immer die bessere Wahl – dieses Kapitel dient primär dazu, das Muster in fremdem Code oder älteren Bibliotheken zu ERKENNEN, nicht dazu, es aktiv einzusetzen.