Navigating and Passing Params Between Screens in React Navigation

May 10, 2023 â‹… Modified: May 22, 2025 â‹… 5 min read

Bilal Arslan

Introduction

In this tutorial, you will learn how to use React Navigation in a React Native project. We will show you how to move between screens and pass data (parameters) from one screen to another. This is a basic but important skill for every React Native developer if you want to go with React Navigation.

Creating Project

npx create-expo-app@latest --template blank-typescript react-navigation-screens

Enter the directory

cd react-navigation-screens

Installing Dependencies

React Navigation is a routing and navigation library for React Native and Web apps.

npm install @react-navigation/native
npx expo install react-native-screens react-native-safe-area-context
npm install @react-navigation/native-stack

Starting the Emulator

npx expo start
  • Boom, our emulator is up and running!
React Navigation Initial Project

Implementation

Let's create our screens and their basic structure:

screens/LoginScreen.tsx
import React from 'react'
import { View, Text } from 'react-native'
 
const LoginScreen = () => {
    return (
        <View style={{ flex: 1, justifyContent: 'center', alignItems: 'center' }}>
            <Text>LoginScreen</Text>
        </View>
    )
}
 
export default LoginScreen;
screens/HomeScreen.tsx
import React from 'react'
import { View, Text } from 'react-native'
 
const HomeScreen = () => {
    return (
        <View style={{ flex: 1, justifyContent: 'center', alignItems: 'center' }}>
            <Text>HomeScreen</Text>
        </View>
    )
}
 
export default HomeScreen;

Also we need to define navigation types, it will help us when calling navigate method

  • When passing to HomeScreen, we need to pass username:string param too.
types/index.ts
export type RootStackParamList = {
    Home: { username: string };
    Login: any;
};

Let's update our project's root file, App.js, and import the screens:

App.tsx
import { StatusBar } from 'expo-status-bar';
 
import { SafeAreaProvider } from 'react-native-safe-area-context';
 
import { NavigationContainer } from '@react-navigation/native';
import { createNativeStackNavigator } from '@react-navigation/native-stack';
 
import LoginScreen from './screens/LoginScreen';
import HomeScreen from './screens/HomeScreen';
 
import { RootStackParamList } from './types';
 
const Stack = createNativeStackNavigator<RootStackParamList>();
 
export default function App() {
  return (
      <SafeAreaProvider style={{ flex: 1 }}>
        <StatusBar style='light' />
        <NavigationContainer>
          <Stack.Navigator initialRouteName='Login' screenOptions={{ headerShown: false }}>
            <Stack.Screen name='Login' component={LoginScreen} />
            <Stack.Screen name='Home' component={HomeScreen} />
          </Stack.Navigator>
        </NavigationContainer>
      </SafeAreaProvider>
  );
}

Now, we can see the LoginScreen.

Login Screen

Let's go back to our LoginScreen and implement the UI:

screens/LoginScree.tsx
import React, { useState } from 'react';
import { StyleSheet, View, Text, TextInput, TouchableOpacity } from 'react-native';
import { NativeStackNavigationProp } from '@react-navigation/native-stack';
import { useNavigation } from '@react-navigation/native';
import { FontAwesome5 } from '@expo/vector-icons';
 
import { RootStackParamList} from "../types";
 
 
type HomeScreenNavigationProp = NativeStackNavigationProp<RootStackParamList, 'Home'>;
 
const LoginScreen = () => {
 
    const navigation = useNavigation<HomeScreenNavigationProp>();
    const [username, setUsername] = useState('');
    const onLogin = () => {
        navigation.navigate('Home', { username: username })
    }
 
    return (
        <View style={{
            flex: 1,
            justifyContent: 'center',
            padding: 20,
            backgroundColor: '#121212'
        }}>
 
            <View style={{
                width: 120,
                height: 120,
                justifyContent: 'center',
                alignItems: 'center',
                borderRadius: 60,
                borderWidth: 1,
                borderColor: '#FFF',
                alignSelf: 'center'
            }}>
                <FontAwesome5 name='user-alt' size={80} color='#FFF' />
            </View>
 
            <TextInput
                style={{
                    color: '#FFF',
                    borderWidth: 1,
                    borderColor: '#FFF',
                    padding: 10,
                    borderRadius: 10,
                    marginTop: 40
                }}
                value={username}
                onChangeText={setUsername}
                placeholder='Your name'
                placeholderTextColor='#FFF' />
 
            <TouchableOpacity
                disabled={username.length < 3}
                style={{
                    borderWidth: 1,
                    borderColor: '#FFF',
                    padding: 15,
                    marginTop: 20,
                    borderRadius: 10,
                    justifyContent: 'center',
                    alignItems: 'center',
                    backgroundColor: '#6D8AFE', opacity: username.length < 3 ? 0.5 : 1
                }}
                onPress={() => onLogin()}>
                <Text style={{
                    color: '#FFF',
                    fontWeight: '600',
                    fontSize: 16
                }}>ENTER</Text>
            </TouchableOpacity>
        </View>
    )
}
 
export default LoginScreen;

The final implementation of LoginScreen is as follows:

Login Screen

When we input the username and press ENTER, the following code block runs, navigating to the HomeScreen and passing the username as a parameter:

screens/LoginScree.tsx
 
    const onLogin = () => {
        navigation.navigate('Home', { username: username })
    }

Okay, let's update the HomeScreen:

screens/HomeScreen.tsx
import React, { useState, useEffect } from 'react';
import { RouteProp, useNavigation } from '@react-navigation/native';
import { View, Text, TouchableOpacity } from 'react-native';
import { FontAwesome5 } from '@expo/vector-icons';
 
import { RootStackParamList } from '../types';
import { NativeStackNavigationProp } from '@react-navigation/native-stack';
 
type HomeScreenRouteProp = RouteProp<RootStackParamList, 'Home'>;
type NavigationProp = NativeStackNavigationProp<RootStackParamList>;
 
type Props = {
    route: HomeScreenRouteProp;
};
 
const icons = [
    { name: 'smile', color: '#FFD700' },
    { name: 'rocket', color: '#FF4500' },
    { name: 'music', color: '#1E90FF' },
    { name: 'gamepad', color: '#00FF7F' },
    { name: 'laugh-beam', color: '#FF69B4' },
];
 
const HomeScreen = ({ route }: Props) => {
    const { username } = route.params;
    const navigation = useNavigation<NavigationProp>();
 
    const [iconIndex, setIconIndex] = useState(0);
 
    useEffect(() => {
        const interval = setInterval(() => {
            setIconIndex((prev) => (prev + 1) % icons.length);
        }, 500);
 
        return () => clearInterval(interval);
    }, []);
 
    const currentIcon = icons[iconIndex];
 
    return (
        <View
            style={{
                flex: 1,
                backgroundColor: '#121212',
                paddingHorizontal: 20,
            }}
        >
            <TouchableOpacity
                onPress={() => navigation.goBack()}
                style={{
                    flexDirection:'row',
                    alignItems:'center',
                    marginTop: 60,
                    padding: 10,
                }}
            >
                <FontAwesome5 name="chevron-left" size={16} color="#FFF" />
 
                <Text
                    style={{
                        marginLeft: 10,
                        color: '#FFF',
                        fontWeight: '800',
                        fontSize: 20
                    }}
                >
                    Welcome, {username}! 👋
                </Text>
 
            </TouchableOpacity>
 
            <View style={{
                flex:1,
                alignItems:'center',
                marginTop: 30
            }}>
                <FontAwesome5
                    name={currentIcon.name as any}
                    size={100}
                    color={currentIcon.color}
                />
                <Text
                    style={{
                        color: currentIcon.color,
                        marginTop: 10,
                        fontSize: 20,
                        textTransform: 'capitalize',
                    }}
                >
                    {currentIcon.name}
                </Text>
            </View>
        </View>
    );
};
 
export default HomeScreen;
 

Yay! Now we have successfully handled the parameter and displayed it on the HomeScreen.

Home Screen with param

The following code block is used to retrieve the parameter:

screens/HomeScreen.tsx
  const { username } = route.params;

The following code block is used to go back to the previous screen:

screens/HomeScreen.tsx
    <TouchableOpacity
                  onPress={() => navigation.goBack()}
                  style={{
                      flexDirection:'row',
                      alignItems:'center',
                      marginTop: 60,
                      padding: 10,
                  }}
              >

Project Dependencies

  "dependencies": {
    "@react-navigation/native": "^7.1.9",
    "@react-navigation/native-stack": "^7.3.13",
    "expo": "~53.0.9",
    "expo-status-bar": "~2.2.3",
    "react": "19.0.0",
    "react-native": "0.79.2",
    "react-native-safe-area-context": "5.4.0",
    "react-native-screens": "~4.10.0"
  },
  "devDependencies": {
    "@babel/core": "^7.25.2",
    "@types/react": "~19.0.10",
    "typescript": "~5.8.3"
  },

Youtube Tutorial Video

This video answers following topics;

  • How to install React Navigation in React Native.
  • How to navigate between screens.
  • How to pass parameters between screens.

Source Code

Github Repository Link

Conclusion

In this tutorial, you learned how to use React Navigation in React Native to move between screens and pass data. This is a simple but important feature for many apps. Now you can create screens, navigate between them, and send information easily. If you want to learn more, check out the video and the GitHub repository.