vom Browser zur nativen App
Wer React im Browser beherrscht, bringt bereits das Kernwissen für React Native mit: Komponenten, Hooks und State funktionieren identisch. Was sich ändert, sind die Bausteine für die Oberfläche, das Styling-Modell und die Art, wie native Funktionen wie Kamera oder Push-Benachrichtigungen angebunden werden. Dieser Artikel zeigt den direkten Umstieg mit konkretem Code.
Inhaltsverzeichnis
- 1. Was React Native wirklich ist
- 2. View, Text und Pressable statt div, span und button
- 3. StyleSheet statt CSS: das Layout-Modell verstehen
- 4. Navigation ohne Browser-Router
- 5. Hooks und State: was unverändert bleibt
- 6. Native Module und Plattform-APIs anbinden
- 7. Plattformunterschiede zwischen iOS und Android
- 8. Typische Einstiegsfehler
- 9. React Web versus React Native im Vergleich
- 10. Zusammenfassung
- 11. FAQ
1. Was React Native wirklich ist
React Native ist kein Browser im Gehäuse, sondern ein Framework, das React-Komponenten in tatsächliche native Oberflächenelemente von iOS und Android übersetzt. Wenn eine Komponente in React Native gerendert wird, entsteht auf iOS eine echte UIView und auf Android eine echte android.view.View. Es gibt kein DOM, keinen Browser-Renderer und kein HTML im Hintergrund. Diese Tatsache ist der wichtigste Unterschied zu Technologien wie Cordova oder älteren WebView-basierten Ansätzen, die letztlich eine Webseite in einem nativen Container anzeigen.
Für Web-Entwickler bedeutet der Einstieg in React Native vor allem ein Umlernen bei den Bausteinen, nicht beim Programmiermodell. JSX, Komponenten, Props, State und Hooks funktionieren identisch. Der React-Reconciler arbeitet nach denselben Regeln, nur dass am Ende der Rendering-Pipeline kein DOM-Baum steht, sondern ein natives View-Baum-Kommando über die sogenannte Bridge beziehungsweise, in neueren Versionen, über das JSI (JavaScript Interface). Wer diesen Unterschied verinnerlicht, versteht sofort, warum manche Web-Bibliotheken in React Native schlicht nicht funktionieren: Alles, was direkt auf document oder window zugreift, hat in der nativen Laufzeitumgebung keine Entsprechung.
Der praktische Einstieg gelingt am schnellsten mit Expo, einem Toolchain-Layer über React Native, der Build-Konfiguration, native Module und Entwicklungsserver bündelt. Für erste Projekte reicht npx create-expo-app völlig aus. Wer später tiefer in native Module einsteigen möchte, kann jederzeit zum Bare Workflow wechseln, dazu mehr im separaten Artikel zum Thema Expo gegenüber Bare React Native.
2. View, Text und Pressable statt div, span und button
Der erste sichtbare Unterschied beim Umstieg auf React Native ist das Fehlen von HTML-Elementen. Statt <div> schreibt man <View>, statt <span> oder <p> schreibt man <Text>. Diese Regel ist strikt: Reiner Text außerhalb eines Text-Elements erzeugt in React Native einen Fehler, während im Browser Textknoten direkt in einem div problemlos erlaubt sind. Diese Striktheit hat einen guten Grund: Native Textrendering benötigt explizite Kontrollstrukturen für Zeilenumbruch, Schriftgröße und Textkürzung, die das Betriebssystem selbst übernimmt.
Für Interaktionen ersetzt Pressable den klassischen button. Pressable ist flexibler als das ältere TouchableOpacity, weil es über die style-Prop eine Funktion entgegennehmen kann, die den aktuellen Press-Zustand liefert. Für Listen mit vielen Einträgen ist FlatList statt einer einfachen map-Schleife über View-Elemente Pflicht, weil FlatList nur die sichtbaren Zeilen rendert und dadurch auch bei tausenden Einträgen performant bleibt.
import { View, Text, Pressable, FlatList, StyleSheet } from 'react-native';
// React Native core components replace HTML elements directly
function ProductList({ products, onSelect }) {
return (
<FlatList
data={products}
keyExtractor={(item) => item.id}
renderItem={({ item }) => (
<Pressable
onPress={() => onSelect(item)}
style={({ pressed }) => [
styles.row,
pressed && styles.rowPressed,
]}
>
<View style={styles.rowContent}>
<Text style={styles.title}>{item.name}</Text>
<Text style={styles.price}>{item.price.toFixed(2)} EUR</Text>
</View>
</Pressable>
)}
/>
);
}
const styles = StyleSheet.create({
row: { paddingVertical: 12, paddingHorizontal: 16 },
rowPressed: { backgroundColor: '#f1f5f9' },
rowContent: { flexDirection: 'row', justifyContent: 'space-between' },
title: { fontSize: 16, fontWeight: '600', color: '#0f172a' },
price: { fontSize: 16, color: '#0284c7' },
});
3. StyleSheet statt CSS: das Layout-Modell verstehen
Es gibt kein CSS in React Native, keine Stylesheets, keine Selektoren, keine Kaskade. Styling erfolgt ausschließlich über JavaScript-Objekte, meist gebündelt mit StyleSheet.create(). Diese Funktion validiert die Eigenschaften zur Laufzeit im Entwicklungsmodus und optimiert die Objekte für den produktiven Betrieb, indem sie IDs statt vollständiger Objekte über die Bridge sendet. Wichtig für Web-Entwickler: Es gibt kein Vererben von Styles über eine Elternhierarchie. Jede Komponente erhält ihre Styles explizit über die style-Prop, es sei denn, man implementiert die Vererbung selbst über Context oder Prop-Drilling.
Das Layout-Modell basiert vollständig auf Flexbox, mit einem entscheidenden Unterschied zum Web: Die Standard-flexDirection in React Native ist column, nicht row wie im Browser. Wer aus der Webentwicklung kommt und Elemente nebeneinander erwartet, muss explizit flexDirection: 'row' setzen. Es gibt außerdem kein Grid-Layout, keine CSS-Variablen im nativen Sinn und keine Media Queries. Für responsive Layouts nutzt man stattdessen die Dimensions-API oder den Hook useWindowDimensions, der bei Rotation oder Split-Screen-Änderungen automatisch neu rendert.
Ein weiterer Unterschied betrifft Einheiten: Es gibt keine Prozentwerte für Schriftgrößen und keine rem-Einheiten. Alle Zahlenwerte in React Native sind dichteunabhängige Pixel, die das Betriebssystem automatisch auf die Pixeldichte des jeweiligen Geräts skaliert. Ein fontSize: 16 sieht auf einem hochauflösenden Gerät genauso groß aus wie auf einem älteren Gerät mit niedrigerer Pixeldichte.
import { View, useWindowDimensions, StyleSheet } from 'react-native';
// Responsive layout without media queries
function ResponsiveGrid({ children }) {
const { width } = useWindowDimensions();
const columns = width > 600 ? 3 : 1;
return (
<View style={[styles.container, { flexDirection: 'row', flexWrap: 'wrap' }]}>
{children.map((child, index) => (
<View key={index} style={{ width: `${100 / columns}%`, padding: 8 }}>
{child}
</View>
))}
</View>
);
}
const styles = StyleSheet.create({
container: { flex: 1 },
});
4. Navigation ohne Browser-Router
Da es keinen Browser gibt, gibt es auch keine URL-Historie im klassischen Sinn und keinen React Router. Für Navigation in React Native hat sich React Navigation als Standardbibliothek etabliert. Sie bildet Stack-, Tab- und Drawer-Navigation über native Übergangsanimationen ab und verwaltet den Navigationszustand als serialisierbaren Baum, der sogar für Deep Linking und Zustandswiederherstellung nach App-Neustart genutzt werden kann.
Der konzeptionelle Unterschied zum Web-Router: Statt Routen über Pfade zu matchen, definiert man in React Native Screens als benannte Komponenten in einem Navigator und navigiert programmatisch mit navigation.navigate('ScreenName', params). Parameter werden nicht über die URL, sondern über ein typisiertes Objekt übergeben, was sich in Kombination mit TypeScript sauber gegen Tippfehler absichern lässt. Wichtig für die Praxis: Jeder Navigator sollte in einer eigenen Datei definiert werden, damit die Navigationsstruktur mit wachsender App übersichtlich bleibt.
5. Hooks und State: was unverändert bleibt
useState, useEffect, useMemo, useCallback, useContext und benutzerdefinierte Hooks verhalten sich in React Native exakt wie in React für den Browser. Das ist eine gute Nachricht für den Umstieg: Ein bestehender Custom Hook zur Formularvalidierung oder zur Datenabfrage mit TanStack Query lässt sich in den meisten Fällen unverändert übernehmen, solange er keine DOM-spezifischen APIs verwendet. Auch der Context-Mechanismus für globalen State funktioniert identisch, ebenso Zustandsmanager wie Zustand oder Redux Toolkit.
Der Unterschied liegt in den Seiteneffekten selbst. Ein useEffect, der im Web einen window.addEventListener('resize', …) registriert, muss in React Native durch Dimensions.addEventListener oder den bereits erwähnten Hook useWindowDimensions ersetzt werden. Effekte, die auf App-Lebenszyklus-Ereignisse reagieren sollen, etwa wenn die App in den Hintergrund wechselt, nutzen die AppState-API statt der Page-Visibility-API des Browsers. Wer diese Übersetzungstabelle für die häufigsten Browser-APIs kennt, überträgt bestehende Web-Logik in React Native in wenigen Minuten statt Stunden.
6. Native Module und Plattform-APIs anbinden
Der größte konzeptionelle Sprung für Web-Entwickler ist der Zugriff auf native Funktionalität wie Kamera, Standort, Push-Benachrichtigungen oder Biometrie. In React Native übernehmen sogenannte Native Module diese Aufgabe: JavaScript-Bibliotheken mit einer nativen Implementierung in Swift oder Objective-C für iOS und in Kotlin oder Java für Android. Für die überwältigende Mehrheit der Anwendungsfälle muss man diese Module nicht selbst schreiben, da das Expo-Ökosystem und Community-Pakete wie react-native-permissions bereits fertige, getestete Implementierungen bereitstellen.
Wichtig ist das Verständnis, dass Zugriffsrechte in React Native explizit auf Betriebssystemebene angefragt werden müssen. Anders als im Browser, wo eine Permission-API im laufenden Betrieb angefragt wird, müssen bei nativen Apps bestimmte Berechtigungen bereits in der Konfigurationsdatei deklariert werden, bei Expo in der app.json, im Bare Workflow direkt in der Info.plist für iOS und der AndroidManifest.xml für Android. Fehlt diese Deklaration, lehnt das Betriebssystem den Zugriff kommentarlos ab, was ein häufiger Fehler bei den ersten eigenen Native-Modul-Integrationen ist.
import * as Location from 'expo-location';
import { useState, useEffect } from 'react';
// Accessing a native device API through an Expo module
function useCurrentLocation() {
const [coords, setCoords] = useState(null);
const [error, setError] = useState(null);
useEffect(() => {
let isMounted = true;
async function requestLocation() {
const { status } = await Location.requestForegroundPermissionsAsync();
if (status !== 'granted') {
if (isMounted) setError('Standortberechtigung verweigert');
return;
}
const position = await Location.getCurrentPositionAsync({});
if (isMounted) setCoords(position.coords);
}
requestLocation();
return () => { isMounted = false; };
}, []);
return { coords, error };
}
7. Plattformunterschiede zwischen iOS und Android
Trotz des Anspruchs, Cross-Platform-Code zu schreiben, unterscheiden sich iOS und Android in React Native an mehreren Stellen sichtbar. Schatten werden auf iOS über die Eigenschaften shadowColor, shadowOffset und shadowOpacity definiert, auf Android hingegen über eine einzige Eigenschaft namens elevation. Wer nur eine der beiden Varianten setzt, sieht auf der jeweils anderen Plattform gar keinen Schatten. Ähnliches gilt für Statusleisten, sichere Bereiche und Tastaturverhalten.
Für plattformspezifischen Code bietet React Native zwei Mechanismen: das Modul Platform mit Platform.OS und Platform.select() für Inline-Verzweigungen, sowie Dateiendungen wie Button.ios.js und Button.android.js, zwischen denen der Bundler automatisch anhand der Zielplattform wählt. Letzteres empfiehlt sich, sobald der plattformspezifische Code mehr als wenige Zeilen umfasst, weil es die Lesbarkeit erheblich verbessert gegenüber verschachtelten Platform.select()-Aufrufen mitten im Layout-Code.
8. Typische Einstiegsfehler
Der häufigste Anfängerfehler ist der Versuch, Web-Bibliotheken direkt in React Native zu importieren, die intern auf document oder localStorage zugreifen. Solche Pakete brechen sofort mit kryptischen Fehlermeldungen zur Laufzeit, da diese Browser-Globals in der nativen Umgebung schlicht nicht existieren. Die Lösung ist immer, gezielt nach einer Bibliothek zu suchen, die explizit für React Native geschrieben wurde, etwa @react-native-async-storage/async-storage als Ersatz für localStorage.
Ein zweiter häufiger Fehler betrifft das Vergessen von SafeAreaView beziehungsweise dem moderneren react-native-safe-area-context. Ohne diese Absicherung rutschen Inhalte auf Geräten mit Notch oder abgerundeten Ecken unter die Statusleiste oder die Home-Indicator-Leiste. Ein dritter Fehler ist die Annahme, dass console.log-Ausgaben in der Produktion genauso performant sind wie im Web: In React Native kosten exzessive Logs messbare Zeit, weil jede Nachricht über die Bridge zum nativen Debugger gesendet wird, sofern kein Remote-Debugging über das JSI aktiv ist.
9. React Web versus React Native im Vergleich
Die folgende Übersicht fasst die zentralen Unterschiede zusammen, die beim Umstieg von React für den Browser zu React Native am häufigsten für Verwirrung sorgen und direkt die Produktivität beim Einstieg beeinflussen.
| Bereich | React Web | React Native | Konsequenz |
|---|---|---|---|
| Basiselemente | div, span, button |
View, Text, Pressable |
Kein HTML, eigenes Komponentenset |
| Styling | CSS, Selektoren, Kaskade | StyleSheet.create() |
Kein Vererben, keine Selektoren |
| Standard-Flex | flexDirection: row |
flexDirection: column |
Layouts oft anders gedacht |
| Navigation | React Router, URL-basiert | React Navigation, Screen-Baum | Kein Pfad-Matching |
| Persistenz | localStorage |
AsyncStorage |
Asynchrone API statt synchron |
Wer diese fünf Punkte verinnerlicht hat, beherrscht bereits den Großteil des konzeptionellen Umstiegs. Der Rest ist Detailarbeit: Plattform-Eigenheiten kennenlernen, das Expo-Ökosystem erkunden und mit echten Geräten testen, da der Simulator nicht jedes Verhalten, etwa Kamera oder Push-Benachrichtigungen, korrekt abbildet.
Mironsoft
React und React Native Entwicklung für Web und Mobile
React Kenntnisse in eine mobile App verwandeln?
Wir begleiten euer Team beim Einstieg in React Native: von der Architekturentscheidung über Native-Module-Integration bis zum App-Store-Rollout, mit Fokus auf Wiederverwendung eures bestehenden React-Wissens.
Architektur-Beratung
Entscheidung zwischen Expo und Bare Workflow für euer konkretes Projekt
Team-Onboarding
React-Web-Entwickler gezielt auf React Native Patterns schulen
Native Module
Anbindung von Kamera, Push-Diensten und Biometrie sauber umsetzen
10. Zusammenfassung
React Native Grundlagen lassen sich in wenigen Kernpunkten zusammenfassen: Das Programmiermodell mit Komponenten, Hooks und State bleibt identisch zu React im Browser, während sich die Bausteine für die Oberfläche und das Styling-Modell grundlegend unterscheiden. View, Text und Pressable ersetzen HTML-Elemente, StyleSheet.create() ersetzt CSS, Flexbox mit der Standardrichtung Spalte statt Zeile bildet das Layout-Fundament. Navigation läuft über React Navigation statt über einen URL-Router.
Wer diese React Native Grundlagen einmal verstanden hat, überträgt bestehendes React-Wissen in kurzer Zeit auf mobile Anwendungen. Der Einstieg über Expo minimiert die native Toolchain-Komplexität am Anfang, während native Module und Plattformunterschiede erst mit wachsender Projektreife relevant werden. Wichtig bleibt, echte Geräte zu testen, denn Simulatoren bilden nicht jedes native Verhalten korrekt ab.
React Native Grundlagen für Web-Entwickler, das Wichtigste auf einen Blick
Komponenten
View, Text, Pressable und FlatList ersetzen HTML-Elemente. Reiner Text muss immer in Text stehen.
Styling
Kein CSS, kein Vererben. StyleSheet.create() mit Flexbox, Standardrichtung ist Spalte statt Zeile.
Programmiermodell
Hooks, Props und State funktionieren identisch zu React im Browser. Custom Hooks sind meist direkt wiederverwendbar.
Native Zugriffe
Kamera, Standort und Push laufen über Native Module. Berechtigungen müssen in der App-Konfiguration deklariert werden.