React Native for React Developers [Part 6: Navigation: Stack Navigation]
Nikola Gorgiev
Software Developer | Flutter Enthusiast | React | React Native | Electron | JavaScript | TypeScript
Navigation
When we want to introduce multiple screens to our application with some nice navigation capabilities I would suggest using this third party library, which is used by most of the developers.?
Installing
To begging, we first need to install the react-navigation package by executing this command in the terminal (I am simply following the getting started guide which you can find here):
npm install @react-navigation/native
This package depends on some other dependencies, so we need to install those too:
npm install react-native-screens react-native-safe-area-context
Then we need to make some changes in the android project, so open the MainActivity.java (which is located in android/app/src/main/java/PROJECT_NAME/MainActivity.java), and in the MainActivity class add the following code:
@Override
protected void onCreate(Bundle savedInstanceState) {
?super.onCreate(null);
}
And don't forget to add the needed import on the top of MainActivity.java:
import android.os.Bundle;
Now you can try running both iOS and Android apps, by running yarn run ios and yarn run android (these are short commands you can use instead of using npx react-native, and you can use them with yarn or npm).
Add stack screen navigation
We can think of a Stack navigation as an Array, where we are maintaining the screens in the Stack navigation by pushing and popping different screens, you can read more about it here.
To use the stack navigation we need to instal the native-stack dependency:
yarn add @react-navigation/native-stack
And after that we need to update the pods by executing pod install in the ios folder of the Project.
Then we need to create our Stack, and you can do this outside our App component for example, like this:
const Stack = createNativeStackNavigator();
function App() {
.
.
.
Next we need to wrap our entire App in a NavigationContainer and its best practice to do this in the App.js. Then we can start creating our Stack navigation:
领英推荐
function App(){
return (
<NavigationContainer>
<Stack.Navigator initialRouteName="Home">
<Stack.Screen
name="Home"
component={HomeScreen}
options={{title: 'Overview'}}
/>
<Stack.Screen
name="Details"
component={DetailsScreen}
options={{title: 'Info'}}
/>
</Stack.Navigator>
</NavigationContainer>
);
}
As you can see, first we need to put all our Screens inside a Stack.Navigator where we can also define our initialRoute, which will be our Home screen in our case, and our screens are identified by the name property, so make sure that the names of our screens are unique and have in mind that they are case sensitive. Then as we can already see from the code above, we are defining all our screens for this Stack navigator where we provide the name and the component for every screen, and we can also add some options to it, in our case we re modifying the title which we can see on the top of the screen, and in our case we have change the ‘Home’ to ‘Overview’ (the name value will be the Screen title by default), you can read more about the different screen options here:
The components we use for the screen are normal components, in which you can also access the navigation prop which can be used for manipulating the Screen stack:
function HomeScreen({navigation}){
return (
<View style={styles.screenContainer}>
<Text>Home Screen</Text>
<Button
title="Go to Details"
onPress={() => navigation.navigate('Details')}
/>
</View>
);
}
From the example above you can see that we can use the navigation prop object to navigate to a different screen, the Details screen in our example, and by calling the navigate() function we are simply pushing the DetailsScreen on the top of our Stack ‘array’.
We can also send some extra info to our screens when navigating to them like this:
navigation.navigate('Details', {
???????????itemId: Math.floor(Math.random() * 100),
???????????otherParam: 'anything here take two',
?????????});
And we can access the data we sent from the route prop that we can access from our screen like this:
function DetailsScreen({navigation, route}){
?const {itemId, otherParam} = route.params;
?return (
???<View style={styles.screenContainer}>
?????<Text>Details Screen</Text>
?????<Text>otherParam: {JSON.stringify(otherParam)}</Text>
?????<Text>itemId: {JSON.stringify(itemId)}</Text>
Here is the entire code of our simple Stack example:
import * as React from 'react';
import {Button, View, Text, StyleSheet} from 'react-native';
import {NavigationContainer} from '@react-navigation/native';
import {createNativeStackNavigator} from '@react-navigation/native-stack';
function HomeScreen({navigation}) {
return (
<View style={styles.screenContainer}>
<Text>Home Screen</Text>
<Button
title="Go to Details"
onPress={() =>
navigation.navigate('Details', {
itemId: Math.floor(Math.random() * 100),
otherParam: 'anything you want here',
})
}
/>
</View>
);
}
function DetailsScreen({navigation, route}) {
const {itemId, otherParam} = route.params;
return (
<View style={styles.screenContainer}>
<Text>Details Screen</Text>
<Text>otherParam: {JSON.stringify(otherParam)}</Text>
<Text>itemId: {JSON.stringify(itemId)}</Text>
<Button
title="Go to Details... again"
onPress={() =>
navigation.navigate('Details', {
itemId: Math.floor(Math.random() * 100),
otherParam: 'anything here take two',
})
}
/>
<Button title="Go back" onPress={() => navigation.goBack()} />
</View>
);
}
const Stack = createNativeStackNavigator();
function App() {
return (
<NavigationContainer>
<Stack.Navigator initialRouteName="Home">
<Stack.Screen
name="Home"
component={HomeScreen}
options={{title: 'Overview'}}
/>
<Stack.Screen
name="Details"
component={DetailsScreen}
options={{title: 'Info'}}
/>
</Stack.Navigator>
</NavigationContainer>
);
}
export default App;
const styles = StyleSheet.create({
screenContainer: {
flex: 1,
alignItems: 'center',
justifyContent: 'center',
},
});
React Native for React Developers [Part 6: Navigation: Stack Navigation]