Navigation

Unlike web development, where the browser itself provides URLs and back/forward history, React Native has no built-in navigation system whatsoever. Moving between screens — a list screen to a detail screen, a login screen to a home screen — is entirely handled by a separate, community-maintained package family: @react-navigation. It's the de facto standard used by the vast majority of React Native apps, and it's what this page focuses on.

Installing React Navigation

React Navigation is split into a small core library plus one or more "navigator" packages, installed separately depending on which navigation pattern you need:

// Core library, required for every setup
npm install @react-navigation/native

// A specific navigator type — stack navigation is the most common starting point
npm install @react-navigation/native-stack

// Plus a few native dependencies React Navigation itself relies on
npm install react-native-screens react-native-safe-area-context
Note: This site's project doesn't run an actual React Native build, so these are the real install commands to run in your own project — follow the official React Navigation setup guide for the exact versions and any platform-specific steps for the navigator types you use.

The Stack Navigator

The Stack Navigator is the most common navigation pattern: screens stack on top of one another, like a deck of cards. Navigating "forward" pushes a new screen on top; the system back button (Android) or edge-swipe gesture (iOS) pops it back off, returning to the previous screen — all handled automatically once it's set up.

import React from 'react';
import { NavigationContainer } from '@react-navigation/native';
import { createNativeStackNavigator } from '@react-navigation/native-stack';
import HomeScreen from './screens/HomeScreen';
import DetailsScreen from './screens/DetailsScreen';

const Stack = createNativeStackNavigator();

export default function App() {
  return (
    <NavigationContainer>
      <Stack.Navigator initialRouteName="Home">
        <Stack.Screen name="Home" component={HomeScreen} />
        <Stack.Screen name="Details" component={DetailsScreen} />
      </Stack.Navigator>
    </NavigationContainer>
  );
}

NavigationContainer wraps the entire navigation tree and must appear exactly once, near the root of your app. Stack.Navigator declares the set of screens available in this stack, and each Stack.Screen maps a string name (used when navigating) to the actual component to render.

Navigating Between Screens

Every screen component registered with a navigator automatically receives a navigation prop, with methods for moving around:

import React from 'react';
import { View, Button } from 'react-native';

export default function HomeScreen({ navigation }) {
  return (
    <View>
      <Button
        title="Go to Details"
        onPress={() => navigation.navigate('Details')}
      />
    </View>
  );
}
MethodPurpose
navigation.navigate('ScreenName')Pushes (or jumps to) the named screen
navigation.goBack()Pops the current screen off the stack, returning to the previous one
navigation.push('ScreenName')Always pushes a new instance of a screen, even the same one already on the stack

Passing Parameters to a Screen

A second argument to navigate lets you pass data along to the destination screen — for example, which item's details to show:

// On the sending screen (e.g. a list item's onPress)
navigation.navigate('Details', { itemId: 42, title: 'Wireless Mouse' });

The receiving screen reads them back off a route prop, which every screen also receives automatically:

import React from 'react';
import { View, Text } from 'react-native';

export default function DetailsScreen({ route }) {
  const { itemId, title } = route.params;

  return (
    <View>
      <Text>Item #{itemId}: {title}</Text>
    </View>
  );
}

route.params is simply the object you passed as the second argument to navigate — plain JavaScript data flowing from one screen to the next.

The Tab Navigator

For a bottom tab bar — the row of icons at the bottom of the screen switching between top-level sections of an app (Home, Search, Profile, etc.) — the equivalent package is @react-navigation/bottom-tabs:

import React from 'react';
import { NavigationContainer } from '@react-navigation/native';
import { createBottomTabNavigator } from '@react-navigation/bottom-tabs';
import HomeScreen from './screens/HomeScreen';
import SettingsScreen from './screens/SettingsScreen';

const Tab = createBottomTabNavigator();

export default function App() {
  return (
    <NavigationContainer>
      <Tab.Navigator>
        <Tab.Screen name="Home" component={HomeScreen} />
        <Tab.Screen name="Settings" component={SettingsScreen} />
      </Tab.Navigator>
    </NavigationContainer>
  );
}

The shape is identical to the Stack Navigator — a navigator component containing Screen children — just a different create*Navigator() function producing a different visual pattern (tabs instead of a pushed/popped stack).

Nesting Navigators

Real apps commonly nest navigators inside one another. A very typical pattern: a Tab Navigator forms the app's main shell, and one of its tabs — say, the "Home" tab — itself contains a full Stack Navigator, so that tapping into a list item from the Home tab pushes a details screen on top, without leaving the Home tab or disturbing the other tabs:

// Conceptual shape — a Stack Navigator living inside one Tab screen
function HomeStack() {
  return (
    <Stack.Navigator>
      <Stack.Screen name="HomeList" component={HomeListScreen} />
      <Stack.Screen name="Details" component={DetailsScreen} />
    </Stack.Navigator>
  );
}

function RootTabs() {
  return (
    <Tab.Navigator>
      <Tab.Screen name="HomeTab" component={HomeStack} />
      <Tab.Screen name="SettingsTab" component={SettingsScreen} />
    </Tab.Navigator>
  );
}

This is conceptual awareness for now — the important takeaway is that navigators compose just like any other React components, and combining a top-level Tab Navigator with per-tab Stack Navigators is an extremely common shape for real, production apps.

Next up: Now that you can move between screens, the next page covers how to collect user input on any given screen with Forms & TextInput.