Dumb Components in React Native: Präsentational vs. Smart
Dumb Components
~9 Min. Lesezeit Zuletzt aktualisiert am 8. August 2026
"Dumb" (bzw. "präsentational") vs. "Smart" (bzw. "Container") ist ein Architekturmuster, das die Verantwortlichkeiten innerhalb einer React-Native-App klar trennt: WAS angezeigt wird, getrennt von WOHER die Daten kommen.
1. Beschreibung
Eine "Dumb Component" (auch "präsentationale Komponente" genannt) kennt NUR ihre Props – sie hat keinen eigenen Datenzugriff (kein fetch(), kein AsyncStorage), keinen eigenen komplexen State, und weiß nichts über die App als Ganzes. Sie bekommt Daten hereingereicht und meldet Ereignisse per Callback-Props nach außen. Das Gegenstück ist eine "Smart Component" (Container), die Daten lädt/verwaltet und an mehrere Dumb Components verteilt.
2. Kurzes Beispiel
// Dumb Component: kennt nur ihre Props, keine eigene Datenlogik
function ProduktZeile({ name, preis, onPress }) {
return (
<TouchableOpacity onPress={onPress}>
<Text>{name} – {preis} €</Text>
</TouchableOpacity>
);
}3. Komplettes Projekt: Smart + Dumb kombiniert
npx create-expo-app dumb-components-demo
cd dumb-components-demoimport { Text, TouchableOpacity, StyleSheet } from 'react-native';
// DUMB: keine Ahnung, woher die Daten kommen, kein eigener State
function ProduktZeile({ name, preis, istFavorit, onToggleFavorit }) {
return (
<TouchableOpacity style={styles.zeile} onPress={onToggleFavorit}>
<Text>{istFavorit ? '★' : '☆'} {name} – {preis.toFixed(2)} €</Text>
</TouchableOpacity>
);
}
const styles = StyleSheet.create({
zeile: { paddingVertical: 12, borderBottomWidth: 1, borderBottomColor: '#e5e7eb' },
});
export default ProduktZeile;import { useState } from 'react';
import { View, FlatList, StyleSheet } from 'react-native';
import ProduktZeile from './components/ProduktZeile';
// SMART: kennt die Datenquelle (hier ein festes Array, in echten Apps z. B. eine API) und den State
const PRODUKTE = [
{ id: '1', name: 'Wanderschuhe', preis: 89.99 },
{ id: '2', name: 'Rucksack', preis: 59.5 },
];
export default function App() {
const [favoriten, setFavoriten] = useState([]);
function toggleFavorit(id) {
setFavoriten((aktuell) =>
aktuell.includes(id) ? aktuell.filter((f) => f !== id) : [...aktuell, id]
);
}
return (
<View style={styles.container}>
<FlatList
data={PRODUKTE}
keyExtractor={(item) => item.id}
renderItem={({ item }) => (
<ProduktZeile
name={item.name}
preis={item.preis}
istFavorit={favoriten.includes(item.id)}
onToggleFavorit={() => toggleFavorit(item.id)}
/>
)}
/>
</View>
);
}
const styles = StyleSheet.create({
container: { flex: 1, paddingTop: 60, paddingHorizontal: 16 },
});4. Erklärung
ProduktZeilehat keinen eigenenuseStatefür den Favoriten-Status – sie bekommtistFavoritals fertigen Wert von außen und meldet einen Klick nur peronToggleFavoritnach oben.Appist die "Smart"-Seite: Sie besitzt denfavoriten-State und die Logik, wie er sich ändert –ProduktZeilemuss davon nichts wissen.
5. Ausgaben
Tipp: Der Vorteil: ProduktZeile lässt sich in JEDER anderen Liste wiederverwenden – auch einer, deren Daten von einer echten API statt einem festen Array kommen – ohne eine einzige Zeile in ProduktZeile.js selbst zu ändern.