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 }) |
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 'react';
import { NavigationContainer } from '@react-navigation/native';
import { createBottomTabNavigator } from '@react-navigation/bottom-tabs';
import { createStackNavigator } from '@react-navigation/stack';
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.NavigatorinsideTab.Navigatorfor 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 | |
| onBlur | Triggered when the screen loses focus | |
| onAppear | Called when screen appears (React Navigation v6+) | |
| onDisappear | Called when screen disappears (React Navigation v6+) | |
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.