In React Navigation 407,918 you type the parameters yourself, as a map from screen name to parameter object, and every screen receives a navigation object and its route:
export type RootStackParamList = {
Catalog: undefined; // no params
Book: { id: number; from?: string };
};
const Stack = createNativeStackNavigator<RootStackParamList>();
type Props<T extends keyof RootStackParamList> = NativeStackScreenProps<RootStackParamList, T>;
// ...in CatalogScreen({ navigation }: Props<'Catalog'>):
<BookRow book={item} onPress={(id) => navigation.navigate('Book', { id })} />)} />
// ...
function BookScreen({ route, navigation }: Props<'Book'>) {
const book = books.find((b) => b.id === route.params.id)!;
const next = books[book.id % books.length];
// ...cover, title, summary, then the Next and Back to the catalog buttons:
onPress={() => navigation.push('Book', { id: next.id, from: book.title })}>
<Pressable style={ui.button} onPress={() => navigation.popTo('Catalog')}>The container's onStateChange logged the stack after each change. Tapping book 2, Next and Back to the catalog:
LOG stack: Catalog > Book{"id":2}
LOG stack: Catalog > Book{"id":2} > Book{"id":3,"from":"Patterns of the Deep Web"}
LOG stack: CatalogUnlike Expo Router 6,418 , parameters here are live JavaScript values: id arrived as the number 2. Keep them small and serializable anyway (ids, not whole book objects), because deep links and state persistence turn them into text. navigate() goes to a screen, push() always adds a new copy (book 3 on top of book 2), popTo() returns to a screen already in the stack, goBack() and popToTop() go back one step or all the way, and setParams() updates the current screen's parameters.
React Navigation 7 changed navigate: in version 6 it went back to a screen already in the stack; now popTo does that (navigateDeprecated keeps the old behavior while you migrate). useNavigation() gives nested components the same object, and createNavigationContainerRef() lets code outside components navigate.