React Native Navigation
In diesem Tutorial zeige ich wie man React Native Navigation verwendet um einzelne Screens zu erstellen und zwischen diesen zu navigieren. Die meisten Apps bestehen aus mehr einem Bildschirm, weshalb die Navigation ein wesentliches Feature ist, dass man als React Native Entwickler kennen muss.
React Native Navigation
Eine Navigation kann zu jeder Zeit in der Entwicklung zum React Native Projekt hinzugefügt werden, in diesem Tutorial starte ich aber mit einem brand neuen Projekt, dazu erstelle ich das Projekt „MyApp“ vom TypeScript Template:
npx react-native init MyApp--template react-native-template-typescript
Ich setze bei all meinen Entwicklungen auf TypeScript, die folgenden Infos lassen sich aber auch bei einem normalen JavaScript Projekt ebenso umsetzen.
Installation
Details für React Native Navigation findet man auf der offiziellen Webseite des Pakets. Die Bibliothek(en) erlauben die definition einzelner Seiten (Screens) und die Navigation von einem zum anderen zu definieren. Um die Navigation nutzen zu können habe ich folgende Pakete installiert:
npm install @react-navigation/native npm install @react-navigation/native-stack npm install react-native-screens npm install react-native-safe-area-context
Verwendung
Die App.tsx aus dem Template habe ich durch folgende ersetzt. In dieser werden alle Screens für die Navigation definiert. Man stellt auch ein, welche der Screens standardmäßig (beim Start der App) angezeigt wird.
import React from 'react'; import { NavigationContainer } from '@react-navigation/native'; import { createNativeStackNavigator } from '@react-navigation/native-stack'; // screens import Home from './screen/Home'; import Tutorial from './screen/Tutorial'; const Stack = createNativeStackNavigator(); interface Props { } interface State { } class App extends React.Component<Props, State> { constructor(props: Props) { super(props); } render() { return ( <NavigationContainer> <Stack.Navigator initialRouteName="Home"> <Stack.Screen name="Home" component={Home} options={{ headerShown: false }} /> <Stack.Screen name="Tutorial" component={Tutorial} options={{ headerShown: false }} /> </Stack.Navigator> </NavigationContainer> ); } }; export default App;
Der NavigationContainer wird mit den Screens befüllt, die über die Navigation erreichbar sein sollen. In meinem Fall ist das die „Home“ Seite, diese wir auch beim Start der App dargestellt (initialRouteName=“Home“). Zusätzlich gibt es noch eine „Tutorial“ Seite. Beide Seiten werden mit einem import Statement eingebunden, müssen im Projekt folglich angelegt werden…
Screens
Im Projekt habe ich zwei BluePrints für Screens erzeugt. Beide geben einfach einen Text mit dem jeweiligen Namen des Screen aus, der Home Screen sieht dabei wie folgt aus:
import React from 'react'; import { SafeAreaView, Text, } from 'react-native'; interface Props { navigation: any, } interface State { } class Home extends React.Component<Props, State> { constructor(props: Props) { super(props); } render() { return ( <SafeAreaView> <Text>Home</Text> </SafeAreaView> ); } }; export default Home;
Jeder Screen der angesteuert werden kann, bekommt über die Props ein Navigation Objekt übergeben. Über dieses lassen sich beispielsweise Parameter mit übergeben. Das Objekt selbst wird auch dazu verwendet um eine Navigation auf einen anderen Screen auszulösen.
Action
Jetzt fehlt nur noch ein Button um vom „Home“ Screen zum „Tutorial“ Screen zu gelangen. Dazu füge ich einen Button mit der onPress Methode hizu, die die navigate Funktion des navigation Objekts aufruft. Als Parameter gibt man den Namen des Ziel-Screens an:
Die Ausgabe ist nicht sehr spannend, da ich bewusst alle Stylings weggelassen habe:
Nach einem Klick auf „Button“ wird der andere Screen angezeigt (zur Verwirrung aller habe ich den Button für den Test von „Tutorial“ wie auf dem Source Code Screenshot zu sehen auf „Button“ umbenannt). Die einzelnen Screens liegen auf einem Stack, d.h. über die Back Taste von Android oder iOS gelangt man jederzeit zum vorherigen Screen. Will man das verhindern wird es etwas komplizierter, ist aber möglich.
Parameter übergeben
Will man Informationen dem aufzurufenden Screen mitgeben, so ist das sehr einfach möglich. Es muss lediglich ein 2. Parameter der navigate Funktion mit einem Objekt verwendet werden:
In diesem Beispiel schicke ich ein Objekt mit einer Variablen mit dem Namen id und dem Wert 0 mit.
Um jetzt im Tutorial Screen die Information auszulesen wir das Props Objekt der Klasse mit dem route Objekt erweitert. Über dieses kommt man mit .params an übergeben Objekt und mit .id bekomme ich den als id übergeben Wert 0.
Werte zurück geben
Der ein oder andere Entwickler fragt sich nun bestimmt: Wenn man einem Screen über die Navigation Werte mitgeben kann, kann man dann nicht auch wieder Werte vom aufgerufenen Screnn an den Aufrufer-Screen zurück geben? Zum Beispiel um einen Status zu aktualisieren, der nach einem Klick auf Back sichtbar wird?
Die kurze Antwort: ja das ist möglich, man kann eine Callback Funktion erstellen und dieser vom aufgerufenen Screen Werte zurück geben. Dafür kann man NativeEventEmitter und EmitterSubscription verwendne. Wie das im Detail funktioniert in einem späteren Artikel mehr.
Fazit
Ich habe gezeigt wie einfach es ist React Native Navigation in eine App einzubauen und wie man von einem Screen zu einem anderen navigiert.