Skip to main content

Implementing Navigation

1. Setting Up React Navigation

Example: Installing and Configuring React Navigation

npm install @react-navigation/native
npm install react-native-screens react-native-safe-area-context
npm install @react-navigation/stack
Package Description Version
@react-navigation/native Core navigation library for React Native 6.1.0
@react-navigation/stack Stack navigator implementation 6.3.0
react-native-screens Performance improvements for screens 3.20.0
react-native-safe-area-context Safe area handling for iOS and Android 4.5.0
Note: On iOS, you must run cd ios && pod install after installing the native dependencies.

Example: Basic Stack Navigator Setup

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

const Stack = createStackNavigator();

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

2. Creating Stack Navigator

Example: Basic Stack Navigator Setup

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

const Stack = createStackNavigator();

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

export default App;
Property Description Default
initialRouteName Name of the screen to start navigation with First screen in stack
screenOptions Global options for all screens in stack {}
headerMode Whether to show header or not 'float' (shows header)
Note: The initialRouteName must match the name of a defined screen.
Warning: Make sure to wrap your navigator inside NavigationContainer.

3. Creating Tab Navigator

Example: Basic Tab Navigator Setup

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

const Tab = createBottomTabNavigator();

function MyTabs() {
  return (
    <NavigationContainer>
      <Tab.Navigator>
        <Tab.Screen name="Home" component={HomeScreen} />
        <Tab.Screen name="Settings" component={SettingsScreen} />
      </Tab.Navigator>
    </NavigationContainer>
  );
}
Property Description Default
screenOptions Object to configure screen options for all tabs {}
initialRouteName Name of the initially selected tab First screen in list
backBehavior Behavior when pressing back button 'initialRoute'
Note: The createBottomTabNavigator requires @react-navigation/bottom-tabs to be installed.

Example: Customizing Tab Appearance

const Tab = createBottomTabNavigator();

function CustomTabNavigator() {
  return (
    <Tab.Navigator
      screenOptions={({ route }) => ({
        tabBarIcon: ({ focused, color, size }) => {
          let iconName;
          if (route.name === 'Home') {
            iconName = focused ? 'home' : 'home-outline';
          } else if (route.name === 'Settings') {
            iconName = focused ? 'settings' : 'settings-outline';
          }
          return <Ionicons name={iconName} size={size} color={color} />;
        },
        tabBarActiveTintColor: 'tomato',
        tabBarInactiveTintColor: 'gray',
      })}>
      <Tab.Screen name="Home" component={HomeScreen} />
      <Tab.Screen name="Settings" component={SettingsScreen} />
    </Tab.Navigator>
  );
}

4. Creating Drawer Navigator

Example: Basic Drawer Navigator Setup

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

const Drawer = createDrawerNavigator();

function MyDrawerNavigator() {
  return (
    <Drawer.Navigator initialRouteName="Home">
      <Drawer.Screen name="Home" component={HomeScreen} />
      <Drawer.Screen name="Profile" component={ProfileScreen} />
    </Drawer.Navigator>
  );
}

export default MyDrawerNavigator;
Property Description Default
initialRouteName Name of the route to start at 'Home'
drawerContent Custom component for drawer content null
drawerPosition Position of drawer: 'left' or 'right' 'left'
drawerStyle Styles for the drawer container null
Note: Drawer Navigator requires @react-navigation/drawer package to be installed.
Warning: Make sure to wrap your Drawer Navigator inside a NavigationContainer.

Example: Custom Drawer Content

import { DrawerContentScrollView, DrawerItem } from '@react-navigation/drawer';

function CustomDrawerContent(props) {
  return (
    <DrawerContentScrollView {...props}>
      <DrawerItem
        label="Home"
        onPress={() => props.navigation.navigate('Home')}
      />
      <DrawerItem
        label="Profile"
        onPress={() => props.navigation.navigate('Profile')}
      />
    </DrawerContentScrollView>
  );
}

// Usage in Drawer.Navigator
<Drawer.Navigator drawerContent={props => <CustomDrawerContent {...props} />}>
  <Drawer.Screen name="Home" component={HomeScreen} />
  <Drawer.Screen name="Profile" component={ProfileScreen} />
</Drawer.Navigator>

5. Passing Parameters Between Screens

Method Description Example
navigation.navigate() Navigates to a screen and passes params navigate('Profile', { userId: 123 })
navigation.push() Pushes a new screen onto the stack with params push('Details', { itemId: 456 })

Example: Accessing Passed Parameters

const { userId } = route.params;
Note: Parameters are passed as a single object and are accessible via route.params.

6. Configuring Screen Options

Option Values Description
title string Sets the title of the screen in the header
headerTitle string Overrides the title in the header
headerTintColor string Color of header text and icons
headerStyle object Customizes the header's background and border
headerBackTitle string Text for back button title (iOS only)
headerBackTitleVisible boolean Controls visibility of back title (iOS only)
headerShown boolean Controls visibility of header
headerLeft function Custom component for left side of header
headerRight function Custom component for right side of header
gestureEnabled boolean Enables/disables swipe back gesture (iOS only)

Example: Setting Header Title and Tint

import { StackNavigator } from 'react-native-screens';

<Stack.Screen
  name="Home"
  component={HomeScreen}
  options={{
    title: 'My Home',
    headerTintColor: '#fff',
    headerStyle: {
      backgroundColor: '#007AFF',
    },
  }}
/>

Example: Hiding Header

<Stack.Screen
  name="Profile"
  component={ProfileScreen}
  options={{
    headerShown: false,
  }}
/>

7. Implementing Custom Transitions

Example: Custom Transition with Animated

import React from 'react';
import { Animated, Easing } from 'react-native';

const CustomTransition = () => {
  const scale = new Animated.Value(1);

  const startTransition = () => {
    Animated.timing(scale, {
      toValue: 1.2,
      duration: 300,
      easing: Easing.ease,
      useNativeDriver: true,
    }).start(() => {
      Animated.timing(scale, {
        toValue: 1,
        duration: 300,
        easing: Easing.ease,
        useNativeDriver: true,
      }).start();
    });
  };

  return (
    <Animated.View
      style={{
        transform: [{ scale }],
        width: 100,
        height: 100,
        backgroundColor: 'blue',
      }}
    >
      <TouchableOpacity onPress={startTransition}>
        <Text>Tap for transition</Text>
      </TouchableOpacity>
    </Animated.View>
  );
};

export default CustomTransition;
Property Description Values Notes
duration Duration of the animation in milliseconds number Default: 250ms
easing Easing function to apply to the animation function Default: Easing.inOut(Easing.ease)
useNativeDriver Whether to use native driver for performance true | false Recommended: true for better performance
Note: Custom transitions can be implemented using Animated API or react-native-reanimated for more complex animations.
Warning: Ensure useNativeDriver is set to true for better performance and smoother animations.

8. Handling Back Button

Property Description Default
backButton Controls whether the back button is shown in the header false
onBackPress Function to handle back button press event undefined

Example: Handling Back Button in Stack Navigator

import { StackNavigator } from 'react-navigation';

const MyStack = StackNavigator({
  Home: {
    screen: HomeScreen,
    navigationOptions: {
      headerBackTitle: 'Back',
      headerLeft: null, // Remove default back button
    },
  },
  Details: {
    screen: DetailsScreen,
    navigationOptions: {
      headerBackTitle: 'Back',
      headerLeft: null, // Remove default back button
    },
  },
}, {
  initialRouteName: 'Home',
  headerMode: 'screen',
});

// Custom back button handling
const handleBackPress = () => {
  // Handle custom logic here
  return true; // Prevent default behavior if needed
};

// Apply to navigator config or screen options
Note: The back button behavior can be customized using navigationOptions or by overriding the default header component.
Warning: Disabling the back button might lead to poor user experience if users cannot navigate back easily.

9. Using Navigation Refs

In React Native, navigation refs are used to programmatically navigate between screens and access navigation state from anywhere in your app. This is particularly useful for handling deep links, global navigation actions, or triggering navigation from components that are not directly part of the navigation stack.

Property Description Usage
navigationRef A ref object that holds a reference to the navigation container. Used to access navigation methods like navigate, goBack, and reset.

Example: Setting up Navigation Ref

import * as React from 'react';
import { NavigationContainer } from '@react-navigation/native';

const navigationRef = React.createRef();

function App() {
  return (
    <NavigationContainer ref={navigationRef}>
      {/* Your navigator content */}
    </NavigationContainer>
  );
}

export { navigationRef };

Example: Using Navigation Ref to Navigate

import { navigationRef } from './App';

function navigateToScreen() {
  navigationRef.current?.navigate('Profile', { userId: 123 });
}

function goBack() {
  navigationRef.current?.goBack();
}
Note: Ensure that the navigation ref is properly initialized before attempting to use it. If used in a component outside of the navigation context, make sure that the ref is correctly passed down or globally accessible.

10. Implementing Nested Navigators

Example: Stack Navigator inside Tab Navigator

import &#x27;react&#x27;;
import { NavigationContainer } from &#x27;@react-navigation/native&#x27;;
import { createBottomTabNavigator } from &#x27;@react-navigation/bottom-tabs&#x27;;
import { createStackNavigator } from &#x27;@react-navigation/stack&#x27;;

const Tab = createBottomTabNavigator();
const Stack = createStackNavigator();

function HomeStack() {
  return (
    <Stack.Navigator>
      <Stack.Screen name="Home" component={HomeScreen} />
      <Stack.Screen name="Details" component={DetailsScreen} />
    </Stack.Navigator>
  );
}

function ProfileStack() {
  return (
    <Stack.Navigator>
      <Stack.Screen name="Profile" component={ProfileScreen} />
      <Stack.Screen name="Settings" component={SettingsScreen} />
    </Stack.Navigator>
  );
}

function MainTabs() {
  return (
    <Tab.Navigator>
      <Tab.Screen name="Home" component={HomeStack} />
      <Tab.Screen name="Profile" component={ProfileStack} />
    </Tab.Navigator>
  );
}

export default function App() {
  return (
    <NavigationContainer>
      <MainTabs />
    </NavigationContainer>
  );
}
Navigator Type Description Usage Notes
Stack.Navigator Nested stack navigator Used inside Tab or Drawer Manages screen transitions within a tab
Tab.Navigator Bottom tab navigator Hosts nested navigators Provides navigation between main sections
Drawer.Navigator Drawer-based navigation Can host nested navigators Useful for side-menu navigation
Note: Nested navigators must be defined as components to avoid re-creating them on every render.

Best Practices for Nested Navigation

  • Use Stack.Navigator inside Tab.Navigator for screen hierarchies within tabs
  • Define nested navigators as separate components to prevent re-renders
  • Use navigation.navigate() to navigate between screens in nested stacks
  • Keep navigation structure shallow for better performance and UX

11. Using Navigation Lifecycle Events

Event Description Usage
onFocus Triggered when the screen comes into focus
const Screen = () => {
  const onFocus = () => console.log('Screen focused');
  return <View onfocus={onFocus}></View>;
};
onBlur Triggered when the screen loses focus
const Screen = () => {
  const onBlur = () => console.log('Screen blurred');
  return <View onblur={onBlur}></View>;
};
onAppear Called when screen appears (React Navigation v6+)
const Screen = () => {
  const onAppear = () => console.log('Screen appeared');
  return <View onappear={onAppear}></View>;
};
onDisappear Called when screen disappears (React Navigation v6+)
const Screen = () => {
  const onDisappear = () => console.log('Screen disappeared');
  return <View ondisappear={onDisappear}></View>;
};
Note: These events are useful for managing side effects like starting/stopping timers or fetching data when a screen becomes active.

12. Implementing Custom Navigators

Example: Custom Stack Navigator

import React from 'react';
import { NavigationContainer } from '@react-navigation/native';
import { createStackNavigator } from '@react-navigation/stack';

const Stack = createStackNavigator();

const CustomStack = ({ children }) => {
  return (
    <Stack.Navigator
      screenOptions={{
        headerStyle: {
          backgroundColor: '#f4511e',
        },
        headerTintColor: '#fff',
        headerTitleStyle: {
          fontWeight: 'bold',
        },
      }}
    >
      {children}
    </Stack.Navigator>
  );
};

export default function App() {
  return (
    <NavigationContainer>
      <CustomStack>
        <Stack.Screen name="Home" component={HomeScreen} />
        <Stack.Screen name="Details" component={DetailsScreen} />
      </CustomStack>
    </NavigationContainer>
  );
}
Property Description Default
initialRouteName Name of the route to start at 'Home'
screenOptions Global options for all screens {}
headerStyle Style for the header {}
headerTintColor Color of header text and icons '#fff'
Note: Custom navigators require careful handling of screen transitions and state management.
Warning: Avoid deeply nested navigators as they can impact performance.

Was this article helpful?