React Native Cheatsheet

React Native Navigation

Use this React Native reference while you build software engineering projects, review code for technical interview prep, or polish examples for a software engineer resume.

React Navigation Setup

The standard navigation library for React Native. This page targets React Navigation v7.

npm install @react-navigation/native
npm install react-native-screens react-native-safe-area-context
cd ios && pod install

# Stack navigator
npm install @react-navigation/native-stack

# Tab navigator
npm install @react-navigation/bottom-tabs

# Drawer navigator
npm install @react-navigation/drawer
npm install react-native-gesture-handler react-native-reanimated

Root Setup

// App.tsx
import { NavigationContainer } from '@react-navigation/native';
import { createNativeStackNavigator } from '@react-navigation/native-stack';

const Stack = createNativeStackNavigator<RootStackParamList>();

export default function App() {
  return (
    <NavigationContainer>
      <Stack.Navigator initialRouteName="Home">
        <Stack.Screen name="Home" component={HomeScreen} />
        <Stack.Screen name="Details" component={DetailsScreen} />
        <Stack.Screen name="Profile" component={ProfileScreen} options={{ title: 'My Profile' }} />
      </Stack.Navigator>
    </NavigationContainer>
  );
}

TypeScript: Typed Params

// types/navigation.ts
export type RootStackParamList = {
  Home: undefined;
  Details: { itemId: number; name: string };
  Profile: { userId: string };
};

// Screen component
import type { NativeStackScreenProps } from '@react-navigation/native-stack';

type Props = NativeStackScreenProps<RootStackParamList, 'Details'>;

function DetailsScreen({ route, navigation }: Props) {
  const { itemId, name } = route.params;
  return <Text>{name}</Text>;
}

// useNavigation hook with types
import { useNavigation } from '@react-navigation/native';
import type { NativeStackNavigationProp } from '@react-navigation/native-stack';

const navigation = useNavigation<NativeStackNavigationProp<RootStackParamList>>();

Stack Navigator

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

const Stack = createNativeStackNavigator();

<Stack.Navigator
  initialRouteName="Home"
  screenOptions={{
    headerStyle: { backgroundColor: '#007AFF' },
    headerTintColor: '#fff',
    headerTitleStyle: { fontWeight: 'bold' },
    headerBackButtonDisplayMode: 'minimal',  // v7; replaces deprecated headerBackTitleVisible
    animation: 'slide_from_right',
    contentStyle: { backgroundColor: '#fff' },
  }}
>
  <Stack.Screen
    name="Home"
    component={HomeScreen}
    options={({ route, navigation }) => ({
      title: 'Home',
      headerRight: () => (
        <Pressable onPress={() => navigation.navigate('Settings')}>
          <Text>⚙</Text>
        </Pressable>
      ),
    })}
  />
  <Stack.Screen
    name="Modal"
    component={ModalScreen}
    options={{ presentation: 'modal' }}  // iOS sheet
  />
</Stack.Navigator>

Stack animation values

'default' | 'fade' | 'fade_from_bottom' | 'flip' | 'simple_push' | 'slide_from_bottom' | 'slide_from_right' | 'slide_from_left' | 'none'

presentation values

'card' | 'modal' | 'transparentModal' | 'containedModal' | 'containedTransparentModal' | 'fullScreenModal' | 'formSheet'

Route Params

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

function DetailsScreen() {
  const route = useRoute();
  const { itemId, name } = route.params as { itemId: number; name: string };
  return <Text>{name}</Text>;
}

// From screen props (preferred with TypeScript)
function DetailsScreen({ route, navigation }: Props) {
  const { itemId } = route.params;
}

Bottom Tab Navigator

import { createBottomTabNavigator } from '@react-navigation/bottom-tabs';

const Tab = createBottomTabNavigator();

<Tab.Navigator
  screenOptions={({ route }) => ({
    tabBarIcon: ({ focused, color, size }) => {
      const iconName = route.name === 'Home' ? 'home' : 'settings';
      return <Icon name={iconName} size={size} color={color} />;
    },
    tabBarActiveTintColor: '#007AFF',
    tabBarInactiveTintColor: '#8E8E93',
    tabBarStyle: { backgroundColor: '#fff', borderTopColor: '#E5E5EA' },
    headerShown: false,
  })}
>
  <Tab.Screen name="Home" component={HomeStack} />
  <Tab.Screen
    name="Search"
    component={SearchScreen}
    options={{ tabBarBadge: 3 }}
  />
  <Tab.Screen name="Profile" component={ProfileScreen} />
</Tab.Navigator>

Drawer Navigator

import { createDrawerNavigator } from '@react-navigation/drawer';

const Drawer = createDrawerNavigator();

<Drawer.Navigator
  screenOptions={{
    drawerPosition: 'left',
    drawerType: 'slide',       // 'slide' | 'front' | 'back' | 'permanent'
    drawerStyle: { width: 280 },
    drawerActiveTintColor: '#007AFF',
    overlayColor: 'rgba(0,0,0,0.5)',
    swipeEnabled: true,
  }}
  drawerContent={(props) => <CustomDrawerContent {...props} />}
>
  <Drawer.Screen name="Home" component={HomeScreen} />
  <Drawer.Screen name="Settings" component={SettingsScreen} />
</Drawer.Navigator>

// Open/close from code
navigation.openDrawer();
navigation.closeDrawer();
navigation.toggleDrawer();

Nested Navigators

// Tabs inside Stack (common pattern)
const RootStack = createNativeStackNavigator();
const MainTab = createBottomTabNavigator();

function MainTabs() {
  return (
    <MainTab.Navigator>
      <MainTab.Screen name="Home" component={HomeScreen} />
      <MainTab.Screen name="Feed" component={FeedScreen} />
    </MainTab.Navigator>
  );
}

function App() {
  return (
    <NavigationContainer>
      <RootStack.Navigator>
        <RootStack.Screen name="Main" component={MainTabs} options={{ headerShown: false }} />
        <RootStack.Screen name="Modal" component={ModalScreen} options={{ presentation: 'modal' }} />
      </RootStack.Navigator>
    </NavigationContainer>
  );
}

Deep Linking

const linking = {
  prefixes: ['myapp://', 'https://myapp.com'],
  config: {
    screens: {
      Home: 'home',
      Details: 'details/:itemId',
      Profile: {
        path: 'user/:userId',
        parse: { userId: (id: string) => parseInt(id) },
      },
    },
  },
};

<NavigationContainer linking={linking} fallback={<ActivityIndicator />}>
  ...
</NavigationContainer>

Expo Router (File-based routing)

npx create-expo-app MyApp --template tabs
app/
├── _layout.tsx       # Root layout (NavigationContainer equivalent)
├── index.tsx         # "/" route
├── (tabs)/
│   ├── _layout.tsx   # Tab layout
│   ├── home.tsx      # "/home"
│   └── profile.tsx   # "/profile"
└── details/
    └── [id].tsx      # "/details/123"
// app/(tabs)/_layout.tsx
import { Tabs } from 'expo-router';

export default function TabLayout() {
  return (
    <Tabs>
      <Tabs.Screen name="home" options={{ title: 'Home' }} />
      <Tabs.Screen name="profile" options={{ title: 'Profile' }} />
    </Tabs>
  );
}

// Navigation in components
import { router, useLocalSearchParams } from 'expo-router';

router.push('/details/42');
router.replace('/login');
router.back();

// In details/[id].tsx
const { id } = useLocalSearchParams();