Navigating and Passing Params Between Screens in React Navigation

May 10, 2023 ⋅ Modified: Jul 2, 2023 ⋅ 5 min read

Bilal Arslan

Hi there! I'm a full-stack developer who loves crafting web and mobile apps. When I'm not coding, I enjoy sharing my knowledge as a technical writer. Let's build something awesome together!

Introduction

In this blog post, we will implement an Expo React Native project that utilizes React Navigation for screen navigation and passing data as parameters between screens. Let's dive right in without wasting any time.

Creating Project

npx create-expo-app react-navigation-screens
  • Enter the directory
cd react-navigation-screens

Installing Dependencies

  • React Navigation
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:
// ./src/screens/LoginScreen.jsx
 
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;
// ./src/screens/HomeScreen.jsx
 
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;
  • Let's update our project's root file, App.js, and import the screens:
// ./App.js
 
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 './src/screens/LoginScreen';
import HomeScreen from './src/screens/HomeScreen';
 
const Stack = createNativeStackNavigator();
 
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:
// ./src/screens/LoginScreen.jsx
 
import React, { useState } from 'react';
import { StyleSheet, View, Text, TextInput, TouchableOpacity } from 'react-native';
import { FontAwesome5 } from '@expo/vector-icons';
 
const LoginScreen = () => {
 
    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:
// ./src/screens/LoginScreen.jsx
 
    const onLogin = () => {
        navigation.navigate('Home', { username: username })
    }
  • Okay, let's update the HomeScreen:
// ./src/screens/HomeScreen.jsx
 
import React, { useState } from 'react';
import { StyleSheet, View, Text, TouchableOpacity } from 'react-native';
import { FontAwesome5 } from '@expo/vector-icons';
 
const HomeScreen = ({ route, navigation }) => {
 
    const { username } = route.params;
 
    return (
        <View style={{
            flex: 1,
            padding: 20,
            backgroundColor: '#121212'
        }}>
 
            <Text style={{
                color: '#FFF',
                fontWeight: '800',
                fontSize: 20,
                marginTop: 20,
                alignSelf: 'center'
            }}>Home</Text>
 
            <Text style={{
                color: '#FFF',
                fontWeight: '400',
                fontSize: 20
            }}>Welcome,</Text>
            <Text style={{
                color: '#FFF',
                fontWeight: '400',
                fontSize: 20
            }}>{username}</Text>
 
        </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:
// ./src/screens/HomeScreen.jsx
 
  const { username } = route.params;

Project Dependencies

"dependencies": {
    "@react-navigation/native": "^6.1.6",
    "@react-navigation/native-stack": "^6.9.12",
    "expo": "~48.0.15",
    "expo-status-bar": "~1.4.4",
    "react": "18.2.0",
    "react-native": "0.71.7",
    "react-native-safe-area-context": "4.5.0",
    "react-native-screens": "~3.20.0"
  }

Youtube Tutorial Video

This video answers following topics;

  • ✅Installing react navigation on React Native.
  • ✅Navigating and change screens on React Native.
  • ✅Passing params between screens on React Native.

Source Code

Github Repository Link

Installation

Clone the repo to your directory and install the packages through npm using:

npm install

Run

Run the project with Metro Bundler

npx expo start

Conclusion

  • This blog post explored the usage of React Navigation in a React Native project. We learned navigating between screens and pass parameters using the React Navigation library. By following the step-by-step instructions, we created a simple login screen and a home screen, allowing users to enter their username and displaying it on the home screen. If you want to contunie implementation, you can check the youtube video at below!