Route parameters allow us to send data from one React Native screen to another. With TypeScript, we can define exactly what parameters a screen accepts and what data types those parameters should have.
Route parameters are values passed from one screen to another during navigation.
For example, a Student List screen can send a student's ID to a Student Details screen.
Student List
↓
studentId = 101
↓
Student Details
Without TypeScript, it is easier to accidentally pass the wrong type of data to a screen.
TypeScript allows us to define whether a parameter should be a
string, number, boolean, object, or another type.
type RootStackParamList = {
Home: undefined;
Details: {
studentId: number;
};
};
Here, the Details screen expects a numeric studentId.
Use undefined when a screen does not require parameters.
type RootStackParamList = {
Home: undefined;
Settings: undefined;
};
These screens can be opened without passing additional data.
type RootStackParamList = {
Home: undefined;
Details: {
studentId: number;
};
};
The studentId must be a number.
navigation.navigate("Details", {
studentId: 101
});
The value 101 is a number, so it matches the defined type.
Suppose the route requires a number.
Details: {
studentId: number;
}
Passing a string instead would be a TypeScript error.
// Incorrect
navigation.navigate("Details", {
studentId: "101"
});
Route parameters can also be strings.
type RootStackParamList = {
Profile: {
userId: string;
};
};
The user ID must now be a string.
navigation.navigate("Profile", {
userId: "USR101"
});
TypeScript checks that userId is a string.
A screen can receive multiple parameters.
type RootStackParamList = {
StudentDetails: {
studentId: number;
name: string;
course: string;
};
};
navigation.navigate("StudentDetails", {
studentId: 101,
name: "Rahul",
course: "React Native"
});
Each value must match the corresponding parameter type.
React Navigation provides NativeStackScreenProps for typing
screen navigation and route properties.
import {
NativeStackScreenProps
} from "@react-navigation/native-stack";
type DetailsProps =
NativeStackScreenProps<
RootStackParamList,
"StudentDetails"
>;
function DetailsScreen({
route
}: DetailsProps): React.JSX.Element {
return (
<Text>
{route.params.name}
</Text>
);
}
The route.params object contains the parameters passed to
the screen.
const studentId: number =
route.params.studentId;
<Text>
Student ID: {studentId}
</Text>
TypeScript knows that studentId is a number.
A parameter can be made optional using ?.
type RootStackParamList = {
Profile: {
userId?: number;
};
};
The screen can be opened with or without userId.
const userId =
route.params.userId;
if (userId !== undefined) {
console.log(userId);
}
Checking for undefined helps safely handle optional parameters.
type RootStackParamList = {
Settings: {
darkMode: boolean;
};
};
The parameter must be either true or false.
A union type can restrict a parameter to specific values.
type RootStackParamList = {
Profile: {
role: "student" | "teacher";
};
};
Only student or teacher is allowed.
navigation.navigate("Profile", {
role: "student"
});
This is valid because student is one of the permitted values.
A route parameter can contain an object with several properties.
interface Student {
id: number;
name: string;
course: string;
}
type RootStackParamList = {
Student: {
student: Student;
};
};
const student: Student = {
id: 101,
name: "Rahul",
course: "React Native"
};
navigation.navigate("Student", {
student
});
The object must match the Student interface.
function StudentScreen({
route
}: StudentProps): React.JSX.Element {
const student =
route.params.student;
return (
<View>
<Text>
ID: {student.id}
</Text>
<Text>
Name: {student.name}
</Text>
<Text>
Course: {student.course}
</Text>
</View>
);
}
type RootStackParamList = {
Home: undefined;
Details: {
studentId: number;
};
};
type HomeProps =
NativeStackScreenProps<
RootStackParamList,
"Home"
>;
function HomeScreen({
navigation
}: HomeProps): React.JSX.Element {
return (
<Button
title="View Student"
onPress={() => {
navigation.navigate(
"Details",
{
studentId: 101
}
);
}}
/>
);
}
any for route data.In larger projects, route parameter types can be stored in a dedicated navigation type file.
// navigation/types.ts
export type RootStackParamList = {
Home: undefined;
StudentDetails: {
studentId: number;
};
Profile: {
userId: string;
};
};
any.type RootStackParamList = {
Home: undefined;
StudentDetails: {
id: number;
name: string;
};
};
navigation.navigate(
"StudentDetails",
{
id: 101,
name: "Rahul"
}
);
Both the parameter names and their types are checked by TypeScript.
import React from "react";
import {
View,
Text,
Button
} from "react-native";
import {
NavigationContainer
} from "@react-navigation/native";
import {
createNativeStackNavigator,
NativeStackScreenProps
} from "@react-navigation/native-stack";
type RootStackParamList = {
Home: undefined;
Details: {
studentId: number;
studentName: string;
};
};
type HomeProps =
NativeStackScreenProps<
RootStackParamList,
"Home"
>;
type DetailsProps =
NativeStackScreenProps<
RootStackParamList,
"Details"
>;
function HomeScreen({
navigation
}: HomeProps): React.JSX.Element {
return (
<View>
<Text>
Student Home
</Text>
<Button
title="Open Student Details"
onPress={() => {
navigation.navigate(
"Details",
{
studentId: 101,
studentName: "Rahul"
}
);
}}
/>
</View>
);
}
function DetailsScreen({
route,
navigation
}: DetailsProps): React.JSX.Element {
return (
<View>
<Text>
Student ID:
{route.params.studentId}
</Text>
<Text>
Student Name:
{route.params.studentName}
</Text>
<Button
title="Go Back"
onPress={() => {
navigation.goBack();
}}
/>
</View>
);
}
const Stack =
createNativeStackNavigator<
RootStackParamList
>();
export default function App(): React.JSX.Element {
return (
<NavigationContainer>
<Stack.Navigator>
<Stack.Screen
name="Home"
component={HomeScreen}
/>
<Stack.Screen
name="Details"
component={DetailsScreen}
/>
</Stack.Navigator>
</NavigationContainer>
);
}
TypeScript makes screen-to-screen data transfer safer. It can identify incorrect parameter names, missing parameters, and incorrect parameter types during development.
Route parameters allow React Native screens to exchange data during navigation. TypeScript allows us to define exactly what data each screen expects.
You should now understand number, string, boolean, optional, union, multiple, and object route parameters, as well as how to access them using typed React Navigation screen props.
undefined for routes without parameters.NativeStackScreenProps to type screen props.route.params to access route data.Question: Where can a React Navigation screen access the parameters passed to it?