Paramclasses Academy - Blog

Tutorials Details

←
Post 19 of 39
→

How to Pass Data Between Screens in React Native ?

How to Pass Data Between Screens in React Native ?

November 5, 2026

1. Introduction

In a mobile application, different screens often need to share information.

For example:

  • A Home Screen displays a list of students.

  • When a user selects a student, the Student Details Screen opens.

  • The Details Screen displays the selected student's information.

  • When a user selects a course, another screen displays course information.

In React Native, React Navigation provides a simple way to pass data between screens using route parameters (params).

In this tutorial, we will learn how to pass and receive data using React Navigation.

2. What Are Navigation Parameters?

Navigation parameters are values that we send from one screen to another during navigation.

For example:

navigation.navigate('StudentDetails', {
  studentId: 101,
});

Here:

  • StudentDetails is the destination screen.

  • studentId is the parameter name.

  • 101 is the value being passed.

The destination screen can receive this value using:

function StudentDetailsScreen({ route }) {
  const { studentId } = route.params;

  return (
    <Text>Student ID: {studentId}</Text>
  );
}

The route.params object contains the parameters passed to the screen.

3. Project Requirements

Make sure you have:

  • Node.js and npm.

  • Visual Studio Code.

  • Expo development environment.

  • Android Emulator or Expo Go.

  • Basic JavaScript knowledge.

  • Basic understanding of React Navigation.

4. Create a React Native Project

Open the terminal and create a new Expo project:

npx create-expo-app@latest StudentDataApp --template blank

Move into the project directory:

cd StudentDataApp

Open the project:

code .

5. Install React Navigation

Install React Navigation and Native Stack Navigator:

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

Install the required Expo-compatible dependencies:

npx expo install react-native-screens react-native-safe-area-context

We will use Stack Navigation to move between the Home, Student Details, and Course Details screens.

6. Understand the Data Flow

Our application will contain three screens:

Home Screen

  • Displays student records.

  • Provides a button for each student.

  • Passes the selected student's ID to the Details Screen.

Student Details Screen

  • Receives the student ID.

  • Finds the corresponding student record.

  • Displays the student's name, course, and email.

  • Provides a button to open Course Details.

Course Details Screen

  • Receives student and course information.

  • Displays the received values.

The application flow:

             HOME SCREEN
                  |
                  |
          Select a Student
                  |
                  v
        STUDENT DETAILS SCREEN
                  |
                  |
           View Course
                  |
                  v
         COURSE DETAILS SCREEN

7. Create the Application

Open App.js and replace the existing code with the following complete example.

Complete App.js Code

import React from 'react';

import {
  View,
  Text,
  Pressable,
  StyleSheet,
  ScrollView,
} from 'react-native';

import {
  NavigationContainer,
  useRoute,
} from '@react-navigation/native';

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

const Stack = createNativeStackNavigator();

// Student Records
const students = [
  {
    id: 101,
    name: 'Rahul Sharma',
    course: 'React Native',
    email: 'rahul@gmail.com',
  },
  {
    id: 102,
    name: 'Priya Verma',
    course: 'JavaScript',
    email: 'priya@gmail.com',
  },
  {
    id: 103,
    name: 'Amit Kumar',
    course: 'Android Development',
    email: 'amit@gmail.com',
  },
];

// ---------------- HOME SCREEN ----------------

function HomeScreen({ navigation }) {
  const openStudent = (studentId) => {
    navigation.navigate('StudentDetails', {
      studentId: studentId,
    });
  };

  return (
    <ScrollView contentContainerStyle={styles.container}>

      <Text style={styles.heading}>
        Student Management App
      </Text>

      <Text style={styles.subtitle}>
        Select a student to view details.
      </Text>

      {students.map((student) => (
        <View key={student.id} style={styles.card}>

          <Text style={styles.name}>
            {student.name}
          </Text>

          <Text style={styles.info}>
            Student ID: {student.id}
          </Text>

          <Text style={styles.info}>
            Course: {student.course}
          </Text>

          <Pressable
            style={styles.button}
            onPress={() => openStudent(student.id)}
          >
            <Text style={styles.buttonText}>
              VIEW DETAILS
            </Text>
          </Pressable>

        </View>
      ))}

    </ScrollView>
  );
}

// ---------------- STUDENT DETAILS SCREEN ----------------

// This component demonstrates the useRoute hook.

function StudentSummary() {
  const route = useRoute();

  const studentId = route.params?.studentId;

  return (
    <Text style={styles.info}>
      Received Student ID: {studentId ?? 'Not available'}
    </Text>
  );
}

function StudentDetailsScreen({ route, navigation }) {

  // Receive the parameter from Home Screen.

  const studentId = route.params?.studentId;

  // Find the matching student record.

  const student = students.find(
    (item) => item.id === Number(studentId)
  );

  if (!student) {
    return (
      <View style={styles.container}>
        <Text style={styles.heading}>
          Student Not Found
        </Text>

        <Pressable
          style={styles.button}
          onPress={() => navigation.goBack()}
        >
          <Text style={styles.buttonText}>
            GO BACK
          </Text>
        </Pressable>
      </View>
    );
  }

  return (
    <View style={styles.container}>

      <Text style={styles.heading}>
        Student Details
      </Text>

      <View style={styles.card}>

        <Text style={styles.name}>
          {student.name}
        </Text>

        <Text style={styles.info}>
          Student ID: {student.id}
        </Text>

        <Text style={styles.info}>
          Email: {student.email}
        </Text>

        <Text style={styles.info}>
          Course: {student.course}
        </Text>

        <StudentSummary />

        <Pressable
          style={styles.button}
          onPress={() => {
            navigation.navigate('CourseDetails', {
              studentName: student.name,
              courseName: student.course,
            });
          }}
        >
          <Text style={styles.buttonText}>
            VIEW COURSE
          </Text>
        </Pressable>

      </View>

    </View>
  );
}

// ---------------- COURSE DETAILS SCREEN ----------------

function CourseDetailsScreen({ route }) {

  // Receive data from Student Details Screen.

  const {
    studentName,
    courseName,
  } = route.params ?? {};

  return (
    <View style={styles.container}>

      <Text style={styles.heading}>
        Course Details
      </Text>

      <View style={styles.card}>

        <Text style={styles.info}>
          Student Name:
        </Text>

        <Text style={styles.name}>
          {studentName ?? 'Not available'}
        </Text>

        <Text style={styles.info}>
          Course Name:
        </Text>

        <Text style={styles.name}>
          {courseName ?? 'Not available'}
        </Text>

      </View>

    </View>
  );
}

// ---------------- STYLES ----------------

const styles = StyleSheet.create({

  container: {
    flexGrow: 1,
    backgroundColor: '#F1F5F9',
    padding: 20,
  },

  heading: {
    fontSize: 25,
    fontWeight: 'bold',
    color: '#1E293B',
    textAlign: 'center',
    marginBottom: 12,
  },

  subtitle: {
    fontSize: 15,
    color: '#64748B',
    textAlign: 'center',
    marginBottom: 20,
  },

  card: {
    backgroundColor: '#FFFFFF',
    padding: 20,
    borderRadius: 12,
    marginBottom: 18,
    elevation: 3,
  },

  name: {
    fontSize: 19,
    fontWeight: 'bold',
    color: '#2563EB',
    marginBottom: 10,
  },

  info: {
    fontSize: 15,
    color: '#475569',
    marginBottom: 10,
  },

  button: {
    backgroundColor: '#2563EB',
    padding: 14,
    borderRadius: 8,
    alignItems: 'center',
    marginTop: 12,
  },

  buttonText: {
    color: '#FFFFFF',
    fontWeight: 'bold',
    fontSize: 14,
  },

});

// ---------------- MAIN APP ----------------

export default function App() {

  return (

    <NavigationContainer>

      <Stack.Navigator
        initialRouteName="Home"
        screenOptions={{
          headerStyle: {
            backgroundColor: '#1E40AF',
          },

          headerTintColor: '#FFFFFF',

          headerTitleStyle: {
            fontWeight: 'bold',
          },
        }}
      >

        <Stack.Screen
          name="Home"
          component={HomeScreen}
          options={{
            title: 'Students',
          }}
        />

        <Stack.Screen
          name="StudentDetails"
          component={StudentDetailsScreen}
          options={{
            title: 'Student Details',
          }}
        />

        <Stack.Screen
          name="CourseDetails"
          component={CourseDetailsScreen}
          options={{
            title: 'Course Details',
          }}
        />

      </Stack.Navigator>

    </NavigationContainer>

  );
}

8. Understand the Important Concepts

A. Passing Data Using navigation.navigate()

This is the main method for sending parameters to another screen.

navigation.navigate('StudentDetails', {
  studentId: 101,
});

Explanation:

  • navigation.navigate() opens the destination screen.

  • StudentDetails identifies the destination.

  • { studentId: 101 } contains the data being passed.

You can pass multiple parameters:

navigation.navigate('StudentDetails', {
  studentId: 101,
  studentName: 'Rahul Sharma',
  courseName: 'React Native',
});

B. Receiving Data Using route.params

Inside the destination screen:

function StudentDetailsScreen({ route }) {

  const { studentId } = route.params;

  return (
    <Text>
      Student ID: {studentId}
    </Text>
  );
}

Here, route.params receives the object passed by the previous screen.

You can also access individual properties directly:

const studentId = route.params.studentId;
const studentName = route.params.studentName;

C. Passing Multiple Values

You can send multiple values in a single navigation call.

navigation.navigate('StudentDetails', {
  name: 'Rahul Sharma',
  email: 'rahul@gmail.com',
  course: 'React Native',
  age: 22,
});

Receive them like this:

const {
  name,
  email,
  course,
  age,
} = route.params;

D. Using the useRoute() Hook

Sometimes a component inside a screen does not directly receive the route prop.

In that situation, you can use useRoute().

Import it:

import { useRoute } from '@react-navigation/native';

Use it inside a component:

function StudentInfo() {

  const route = useRoute();

  const studentId = route.params?.studentId;

  return (
    <Text>
      Student ID: {studentId}
    </Text>
  );
}

useRoute() provides access to the current screen's route information.

E. Handling Optional Parameters

Sometimes a screen may open without receiving a parameter.

Instead of directly accessing a possibly missing value:

const studentId = route.params.studentId;

Use optional chaining:

const studentId = route.params?.studentId;

You can also provide a default value:

const studentName = route.params?.studentName ?? 'Guest Student';

This prevents errors when a parameter is missing.

F. Passing Data to Nested Screens

If your application contains nested navigators, you can pass parameters to a screen inside another navigator.

Example:

navigation.navigate('Main', {
  screen: 'Profile',
  params: {
    userId: 101,
  },
});

Here:

  • Main is the parent navigator's screen.

  • Profile is the nested screen.

  • userId is the parameter passed to Profile.

The exact parent and child route names must match your navigator configuration.

9. Updating Navigation Parameters

React Navigation also provides methods to update route parameters.

Example:

navigation.setParams({
  studentName: 'Rahul Verma',
});

This updates the current screen's parameters by merging the new values with the existing ones.

Use setOptions() to update screen options such as the header title, rather than using navigation parameters for that purpose.

10. What Data Should We Pass Between Screens?

You can pass:

  • Student IDs.

  • Product IDs.

  • User IDs.

  • Course names.

  • Search filters.

  • Sorting options.

  • Page numbers.

  • Small pieces of screen-specific input data.

For example:

navigation.navigate('Profile', {
  userId: 101,
});

It is generally better to pass an ID and retrieve the full record from an API or shared data store than to pass a large object through navigation.

Navigation parameters should normally contain JSON-serializable values such as strings, numbers, booleans, arrays, and plain objects.

Avoid passing functions, class instances, or other non-serializable values.

Also avoid using reserved nested-navigation parameter names such as screen, params, initial, and state for your own application data.

11. Run the Application

Start the Expo development server:

npx expo start

Then open the application using Expo Go or your Android Emulator.

Practical Testing Steps

  1. Open the Student Management App.

  2. You will see three student records.

  3. Select Rahul Sharma.

  4. The Student Details screen will open.

  5. Check the received Student ID.

  6. Verify the student's name, email, and course.

  7. Select View Course.

  8. The Course Details screen will open.

  9. Verify that the student name and course name are displayed.

Repeat the same process for Priya Verma and Amit Kumar.

12. Common Errors and Solutions

Error 1: Cannot read properties of undefined

Possible reason: You are trying to access a parameter that was not passed.

Solution:

const studentId = route.params?.studentId;

Error 2: Destination screen does not open

Possible reason: The route name is incorrect.

Solution:

navigation.navigate('StudentDetails', {
  studentId: 101,
});

Check that the navigator contains a screen registered with exactly the same name.

Error 3: Parameter value is undefined

Possible reason: The parameter name is different in the sending and receiving screens.

Incorrect:

navigation.navigate('StudentDetails', {
  studentID: 101,
});
const { studentId } = route.params;

Correct:

navigation.navigate('StudentDetails', {
  studentId: 101,
});
const { studentId } = route.params;

Error 4: Student details are not displayed

Possible reason: The ID does not match any student record.

Solution:

const student = students.find(
  (item) => item.id === Number(studentId)
);

Check the ID and handle the case where no matching student exists.

13. Best Practices

  • Use meaningful parameter names.

  • Pass only the information required by the destination screen.

  • Prefer IDs instead of large data objects.

  • Use optional chaining when parameters may be missing.

  • Keep parameter values JSON-serializable.

  • Validate parameters before using them.

  • Avoid passing sensitive information through navigation parameters.

  • Use an API or shared state for larger application data.

  • Keep screen names consistent across the application.

14. Conclusion

In this tutorial, we learned how to pass data between screens in React Native using React Navigation.

We implemented a Student Management App with three screens:

  • Home Screen.

  • Student Details Screen.

  • Course Details Screen.

We also learned about navigation.navigate(), route.params, useRoute(), optional parameters, nested navigation, and navigation.setParams().

These concepts are important when developing real-world applications such as student management systems, shopping apps, booking apps, and social media applications.

15. Frequently Asked Questions

Q1. How do we pass data between two screens in React Native?

Use navigation.navigate() and pass an object as the second argument.

Q2. How do we receive data on another screen?

Use route.params inside the destination screen component.

Q3. What is useRoute()?

useRoute() is a React Navigation hook that provides access to the current route object.

Q4. Can we pass multiple parameters between screens?

Yes. You can pass multiple values inside one JavaScript object.

Q5. Can we pass an array or object?

Yes. Plain arrays and objects can be passed when they contain JSON-serializable values.

Q6. Should we pass an entire student record?

Usually, passing the student's ID is better. The destination screen can retrieve the complete record from an API or shared data store.

Q7. Can we pass data to a nested screen?

Yes. Use the parent screen name along with the nested screen name and its parameters.

Q8. What happens if a parameter is not provided?

The value may be undefined. Use optional chaining and default values to handle missing parameters safely.

←
Post 19 of 39
→