How to add Stack Navigation in our react-native project

Stack navigation is the basic need of a mobile app to navigate from screen to screen. Today we’re going to see how we can implement it.

NOTE: For the typescript example scroll to the end.

Start by installing these libraries:

npm i @react-navigation/stack
npm i @react-navigation/native

npm i react-native-reanimated react-native-gesture-handler react-native-screens react-native-safe-area-context @react-native-community/masked-view

After that do this mandatory step for iOS

cd ios && pod install && cd ..

Next open App.js or any other file if you want to manage navigation from another file but just make sure that this file is the one that gets executed before everything else loads. Import these two:

import { NavigationContainer } from '@react-navigation/native';
import { createStackNavigator } from '@react-navigation/stack';

Add the following line above the function App(props) {

const Stack = createStackNavigator();

Then add all the screens inside a navigationContainer like this:

<NavigationContainer>
    <Stack.Navigator>
        <Stack.Screen name="Home" component={Home} />
        <Stack.Screen name="Screen 2" component={Screen2} />
        <Stack.Screen name="Screen 3" component={Screen3} />
   </Stack.Navigator>
</NavigationContainer>

Now to navigate from Home to Screen 2 we’ll do

function Home({ navigation }) {
...
<TouchableOpacity onPress={() => {
    navigation.navigate("Screen 2")
}}>
    <Text>Press me to go to Screen 2</Text>
</TouchableOpacity>
...

To pass parameters with navigation:

function Screen2({ route, navigation }) {
    const { name, occupation } = route.params;

...
    return(
        <View><Text>`Name is ${name}, Occupation is ${occupation}`</Text></View>
    )
...

The above code shows how you can capture data passed via params o avigation. Below is how you can pass values to name and occupation from the screen it’s being navigated from:

function Home({ navigation }) {
...
<TouchableOpacity onPress={() => {
    navigation.navigate("Screen 2", {
        name: 'Talha',
        occupation: 'Software Egineer',
    })
}}>
    <Text>Press me to go to Screen 2</Text>
</TouchableOpacity>
...

This will pass an object that we’re then breaking into the Screen2 file.

To go back to the previous screen programmatically you can do:

navigation.goBack()

You can use the above code on a button press or when a function completes execution however you like.

Next, we’ll see how we can change the title of navigation from a screen. Let’s say on Screen 2 the title right now is Screen 2 and I want to change it to the name of the person that we’re passing via route.params as seen previously. To do that here is what we need to do in Screen 2:

import React, { useCallback } from 'react';
import { useFocusEffect } from '@react-navigation/native';

function Screen2({ route, navigation }) {
    const { name, occupation } = route.params;

    useFocusEffect(
        useCallback(() => {
            navigation.setOptions({
                headerTintColor: '#000',
                cardStyle: { backgroundColor: '#FFFFFF' },
                headerStyle: {
                    backgroundColor: '#fff',
                    shadowOpacity: 0,
                    shadowOffset: {
                        height: 0,
                    },
                    shadowRadius: 0,
                    elevation: 0
                },
                headerBackTitle: ' ',
                headerTitle: name
                headerRight: () => <TouchableOpacity style={{ marginRight: 10 }} onPress={() => {
                    Alert.alert("This is a right button", "You can add a components like this or header right side")
                }}>
                    <Text style={{ color: 'tomato' }}>Click Me</Text>
                </TouchableOpacity>
            })
        }, [navigation]))

You can completely modify the navigation bar. You can eve loa these settings from a common file but you now have an idea of how to modify the navigation bar for a specific screen.

If you want to navigate to a specific screen in a Stack Navigator you can do:

              navigation.navigate("Food", {
                screen: "Search",
              });
Possible Errors

If there is something wrong with the reanimated library: https://docs.swmansion.com/react-native-reanimated/docs/fundamentals/installation/#babel-plugin

If you’re facing this error

Invariant Violation: requireNativeComponent: "RNSScreen" was not found in the UIManager.

Make sure in your package.sjon ile if you have the following packages:

  • @react-native-community/masked-view
  • @react-navigation/native
  • @react-navigation/stack
  • react-native-gesture-handler
  • react-native-reanimated
  • react-native-safe-area-context
  • react-native-screens

Next, ensure if you have pods up-to-date (For iOS only) by making sure cd ios –> pod install –> cd ..

And finally, cancel the current build by pressing Ctrl+C (twice/thrice) and then do npx react-native run-ios or running from XCode.

Typescript Example:

Install these:

yarn add @react-navigation/native
yarn add @react-navigation/stack

yarn add react-native-screens react-native-safe-area-context
yarn add react-native-gesture-handler

Then do:

npx pod-install ios

Then in index.js add:

import 'react-native-gesture-handler';

Then open file android/app/src/main/jaa/com/YOUR_APP_NAME/MainActivity.java and add:

import android.os.Bundle;

//... other imports


public class MainActivity extends ReactActivity {
//... code inside the class

  @Override
  protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(null);
  }

} //End of MainActivity class

Then to display it open App.tsx and add:

import React from 'react';

import { NavigationContainer } from '@react-navigation/native';
import { createStackNavigator } from '@react-navigation/stack';

import LoginScreen from '../views/Login';
import HomeScreen from '../views/Home';

type RootStackParamList = {
    Login: undefined;
    Home: undefined;
}

const RootStack =  createStackNavigator<RootStackParamList>();

const App = () => {
	return (
		<NavigationContainer>
			<RootStack.Navigator initialRouteName="Home">
				<RootStack.Screen name="Home" component={HomeScreen} />
				<RootStack.Screen name="Login" component={LoginScreen} />
			</RootStack.Navigator>
		</NavigationContainer>	);
};

export default App;

To navigate from Home to Login add this to your HomeScreen.tsx

import React from 'react';
import { Text, TouchableOpacity } from 'react-native';
import { useNavigation } from '@react-navigation/native';
import { StackNavigationProp } from '@react-navigation/stack';

type HomeScreenOwnProps = StackNavigationProp<RootStackParamList, 'Home'>;

const HomeScreen = (props: any) => {

  const navigation = useNavigation<HomeScreenOwnProps>();
  
  return (
    <TouchableOpacity onPress={()  => 
     navigation.navigate('Login')}>
    <Text>Go to login</Text>
    </TouchableOpacity>
  );
};

export default HomeScreen;

Click don’t he Go to Login and it should navigate successfully:

Leave a comment

Design a site like this with WordPress.com
Get started