Type-safe navigation with nested stacks and tabs.
navigate
and route params.// navigation/types.ts
export type RootStackParamList = {
Home: undefined;
Details: { id: string };
};
// AppNavigator.tsx
import { NavigationContainer } from "@react-navigation/native";
import { createNativeStackNavigator } from "@react-navigation/native-stack";
import type { RootStackParamList } from "./navigation/types";
const Stack = createNativeStackNavigator<RootStackParamList>();
export function AppNavigator() {
return (
<NavigationContainer>
<Stack.Navigator>
<Stack.Screen name="Home" component={HomeScreen} />
<Stack.Screen name="Details" component={DetailsScreen} />
</Stack.Navigator>
</NavigationContainer>
);
}
Typed root stack + two screens navigating with params.
// navigation/types.ts
export type RootStackParamList = { Home: undefined; Details: { id: string } };
// screens/HomeScreen.tsx
import React from "react";
import { View, Text, Button } from "react-native";
import type { NativeStackScreenProps } from "@react-navigation/native-stack";
import type { RootStackParamList } from "../navigation/types";
type Props = NativeStackScreenProps<RootStackParamList, "Home">;
export function HomeScreen({ navigation }: Props) {
return (
<View style={{ padding: 16 }}>
<Text>Home</Text>
<Button
title="Go to Details 42"
onPress={() => navigation.navigate("Details", { id: "42" })}
/>
</View>
);
}
// screens/DetailsScreen.tsx
import React from "react";
import { View, Text } from "react-native";
import type { NativeStackScreenProps } from "@react-navigation/native-stack";
import type { RootStackParamList } from "../navigation/types";
type Props = NativeStackScreenProps<RootStackParamList, "Details">;
export function DetailsScreen({ route }: Props) {
return (
<View style={{ padding: 16 }}>
<Text>Details for {route.params.id}</Text>
</View>
);
}
// AppNavigator.tsx
import React from "react";
import { NavigationContainer } from "@react-navigation/native";
import { createNativeStackNavigator } from "@react-navigation/native-stack";
import type { RootStackParamList } from "./navigation/types";
import { HomeScreen } from "./screens/HomeScreen";
import { DetailsScreen } from "./screens/DetailsScreen";
const Stack = createNativeStackNavigator<RootStackParamList>();
export function AppNavigator() {
return (
<NavigationContainer>
<Stack.Navigator>
<Stack.Screen name="Home" component={HomeScreen} />
<Stack.Screen name="Details" component={DetailsScreen} />
</Stack.Navigator>
</NavigationContainer>
);
}
Notes
Paste into an Expo app (see sandboxes/react-native-expo):