React Native Navigation
React Native bietet standardmäßig 3 verschiedene Navigationen an:
- Stack Navigator
- Drawer Navigator
- Tab Navigator
Diese möchte ich im folgenden näher vorstellen. Wie immer gilt vollständige Codes des Beispiels findet ihr auf GitHub.
Generelles
Zunächst werden für alle Navigator das Paket @react-navigation/native
benötigt. Ebenso wird für die verschiedenen Screen das Paket react-native-screens
benötigt. Diese lassen sich mit npm installieren.
npm i @react-navigation/native react-native-screens
Zudem müssen noch folgende Zeilen eingefügt werden um react-native-screens zu aktivieren.
import { enableScreens } from 'react-native-screens';
enableScreens();
Der Aufbau aller Navigatoren ist ähnlich. Es wird ein NavigationContainer benötigt, in dem jeweils einzelne Screens hinzugefügt werden. Bei den Screens wird dann anhand des component-Attributs festgestellt welcher Screen dargestellt werden soll.
Zudem sollte immer ein Prop erzeugt werden, damit man keinen any-Definition benötigt, wenn man die "navigation" den einzelnen Screens übergibt. Alternativ kann man auch mit Klassenarbeiten und auf den Prop selbst zugreifen.
Stack Navigator
Der Stack Navigator kann man sich vorstellen, wie einen Stapel von Seiten. Hier kann man eine neue Seite draufpacken oder eben zu der vorigen zurückspringen. Ein Basisbeispiel sieht dann wie folgt aus: Übter StackParamList könnte man den einzelnen Screens noch Parameter mitgeben, wenn dies benötigt werden würde.
type StackParamList = {
Home: undefined,
Settings: undefined;
};
type StackProp = {
navigation: StackNavigationProp<StackParamList,'Home'>;
}
const Stack = createStackNavigator<StackParamList>();
export default function App() {
return (
<NavigationContainer>
<Stack.Navigator>
<Stack.Screen name="Home" component={Home} />
<Stack.Screen name="Settings" component={Settings} />
</Stack.Navigator>
</NavigationContainer>
);
}
Der Stack Navigator bietet im Verlgeich zu den andren Navigationen bereits einen Header mit, falls dieser einem nicht zusagt kann man ihn auch customizen oder deaktiveren. Der Vorteil dabei das Steuerungselement zurück und der Name des Screens werden automatisch aufgelöst. Die Navigation auf eine neue Seite muss man jedoch selbst erledigen, dies ist etwa mit einem Button möglich und sieht wie folgt aus.
function Home({navigation}:StackProp) {
return (
<Container>
<Content>
<Button bordered dark onPress={() => navigation.navigate('Settings') }>
<Text>zu Settings wechseln</Text>
</Button>
</Content>
</Container>
);
}
Praktisch sieht der Stack Navigator dann wie folgt aus:
Drawer Navigator
Ein Drawer Navigator ist dann das klassische Menu an der Seite welches man aufschieben kann und sich zwischen Screens bewegen kann. Ein Basisbeispiel sieht dann wie folgt aus:
type DrawerParamList = {
Home: undefined,
Settings: undefined;
};
type DrawerProp = {
navigation: DrawerNavigationProp<DrawerParamList, 'Home'>;
}
const Drawer = createDrawerNavigator();
export default function App() {
return (
<NavigationContainer>
<Drawer.Navigator>
<Drawer.Screen name="Home" component={Home} />
<Drawer.Screen name="Settings" component={Settings} />
</Drawer.Navigator>
</NavigationContainer>
);
}
Beim Drawer Navigator gibt es defaultmäßig keinen Header. Da man jedoch neben der standardmäßig vorhandenen Wischgeste, um das Menu zu öffnen, oftmals einen Button anbietet das Menu zu öffnen, erstelle ich hier einen Header für diesen Zweck. Das kann beispielsweise so aussehen:
function Home({ navigation }: DrawerProp) {
return (
<Container>
<Header>
<Left>
<Icon ios='ios-menu' android="md-menu" onPress={navigation.openDrawer} />
</Left>
<Body>
<Text>Home</Text>
</Body>
</Header>
<Content>
<Text>Home</Text>
</Content>
</Container>
);
}
Das Ergebnis schaut dann in etwa so aus:
Tab Navigator
Das letzte, auch aus diversen Apps bekannte Menu ist der Tab Navigator. Meist befindet dieser sich am Fuße einer Seite und beinhaltet verschiedene Reiter zwischen denen man auswählen kann. Ein Beispiel hierfür lässt sich so realisieren:
type TabParamList = {
Home: undefined,
Settings: undefined;
};
const Tab = createBottomTabNavigator<TabParamList>();
export default function App() {
return (
<NavigationContainer>
<Tab.Navigator>
<Tab.Screen name="Home" component={Home}
options={{tabBarIcon: ({}) => (<Icon ios='ios-home' android="md-home" />)}} />
<Tab.Screen name="Settings" component={Settings}
options={{tabBarIcon: ({}) => (<Icon ios='ios-settings' android="md-settings" />)}} />
</Tab.Navigator>
</NavigationContainer>
);
}
Im Gegensatz zum Drawer Navigator kann ich hier in den Optionen bereits mit angeben, welche Icons für die einzelnen Tabs verwendet werden sollen.
Das sieht in meinem Beispiel dann so aus:
So damit wären wir wohl mit den absoluten Basics durch. Jetzt könnte die Serie in verschiedene Richtungen weiter gehen, was interessiert denn euch?