Configuring Navigation Options
1. Customizing Header Styles
| Property | Description | Values |
|---|---|---|
| headerStyle | Customizes the header's background color, height, etc. | { backgroundColor: '#3b5998' } |
| headerTitleStyle | Customizes the title's font, color, etc. | { fontSize: 20, color: '#fff' } |
| headerTintColor | Sets the color of header icons and title text | '#fff' |
| headerBackTitle | Customizes the back button title | 'Back' |
| headerBackTitleStyle | Customizes the back title's font and color | { fontSize: 16, color: '#fff' } |
Example: Customizing Header Styles
import { NavigationContainer } from '@react-navigation/native';
import { createStackNavigator } from '@react-navigation/stack';
const Stack = createStackNavigator();
function MyStack() {
return (
<NavigationContainer>
<Stack.Navigator
screenOptions={{
headerStyle: {
backgroundColor: '#3b5998',
},
headerTintColor: '#fff',
headerTitleStyle: {
fontWeight: 'bold',
},
}}
>
<Stack.Screen
name="Home"
component={HomeScreen}
options={{
headerBackTitle: 'Return',
headerBackTitleStyle: {
fontSize: 16,
color: '#fff'
}
}}
/>
</Stack.Navigator>
</NavigationContainer>
);
}
2. Using Custom Header Components
| Property | Description | Example |
|---|---|---|
| header | Custom component to render as the header | { header: () => <CustomHeader /> } |
| headerTitle | Text to display as the header title | { headerTitle: 'My App' } |
| headerLeft | Component to render on the left side of header | { headerLeft: () => <BackButton /> } |
| headerRight | Component to render on the right side of header | { headerRight: () => <MenuButton /> } |
Example: Custom Header Component
import React from 'react';
import { View, Text, StyleSheet } from 'react-native';
const CustomHeader = () => {
return (
<View style={styles.header}>
<Text style={styles.title}>My App</Text>
</View>
);
};
const styles = StyleSheet.create({
header: {
backgroundColor: '#2c3e50',
paddingVertical: 15,
alignItems: 'center',
},
title: {
color: '#ecf0f1',
fontSize: 20,
fontWeight: 'bold',
},
});
export default CustomHeader;
Example: Using Custom Header in Stack Navigator
import { createStackNavigator } from '@react-navigation/stack';
import CustomHeader from './CustomHeader';
const Stack = createStackNavigator();
<Stack.Navigator
screenOptions={{
header: (props) => <CustomHeader {...props} />,
}}
>
<Stack.Screen name="Home" component={HomeScreen} />
</Stack.Navigator>
3. Hiding and Showing Headers
| Property | Values | Description |
|---|---|---|
| headerShown | true | false |
Controls visibility of the header. Defaults to true. |
| header | undefined | null | function |
Custom header component or null to hide. Overrides headerShown. |
Example: Hide Header in Stack Navigator
import { createStackNavigator } from '@react-navigation/stack';
const Stack = createStackNavigator();
<Stack.Navigator>
<Stack.Screen
name="Home"
component={HomeScreen}
options={{
headerShown: false,
}}
/>
</Stack.Navigator>
Example: Custom Header Component
import { createStackNavigator } from '@react-navigation/stack';
const Stack = createStackNavigator();
const CustomHeader = () => (
<View style={{ height: 60, backgroundColor: '#f0f0f0' }}>
<Text>Custom Header</Text>
</View>
);
<Stack.Navigator>
<Stack.Screen
name="Profile"
component={ProfileScreen}
options={{
header: CustomHeader,
}}
/>
</Stack.Navigator>
4. Implementing Header Buttons
| Property | Description | Example |
|---|---|---|
| headerRight | Component to render on the right side of the header | {() => <Button title="Save" onPress={handleSave} />} |
| headerLeft | Component to render on the left side of the header | {() => <Button title="Back" onPress={handleBack} />} |
| headerTitle | Custom title component or string for the header | {() => <Text style={{ fontWeight: 'bold' }}>My App</Text>} |
Example: Header Right Button
import { HeaderButtons, Item } from 'react-navigation-header-buttons';
const MyHeaderRight = () => (
<HeaderButtons LeftButtonComponent={Item}>
<Item title="Save" onPress={() => console.log('Saved')} />
</HeaderButtons>
);
// In navigation options:
navigationOptions = {
headerRight: MyHeaderRight,
};
Example: Header Left Button
import { HeaderButtons, Item } from 'react-navigation-header-buttons';
const MyHeaderLeft = () => (
<HeaderButtons RightButtonComponent={Item}>
<Item title="Menu" onPress={() => console.log('Menu opened')} />
</HeaderButtons>
);
// In navigation options:
navigationOptions = {
headerLeft: MyHeaderLeft,
};
Note: The
headerRight and headerLeft properties are part of the navigationOptions object in React Navigation v4 and earlier. For newer versions, use headerRight in the screen options or stack navigator config.
5. Using Tab Bar Icons and Labels
| Property | Description | Values | Notes |
|---|---|---|---|
| tabBarIcon | Function to render the icon for the tab | (props) => ReactNode |
Used in Tab Navigator to customize icons |
| tabBarLabel | Text label for the tab | string | (props) => ReactNode |
Can be a string or a function returning JSX |
| tabBarActiveTintColor | Color of the active tab icon and label | string |
Applies to both icon and label when active |
| tabBarInactiveTintColor | Color of the inactive tab icon and label | string |
Applies to both icon and label when inactive |
Example: Custom Tab Bar Icons and Labels
import { createBottomTabNavigator } from '@react-navigation/bottom-tabs';
import { Ionicons } from '@expo/vector-icons';
const Tab = createBottomTabNavigator();
function MyTabs() {
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} />;
},
tabBarLabel: ({ focused }) => (
<span style={{ color: focused ? '#007AFF' : '#8E8E93' }}>
{route.name}
</span>
),
tabBarActiveTintColor: '#007AFF',
tabBarInactiveTintColor: '#8E8E93'
})}
>
<Tab.Screen name="Home" component={HomeScreen} />
<Tab.Screen name="Settings" component={SettingsScreen} />
</Tab.Navigator>
);
}
Note: The
tabBarIcon function receives navigation props including focused, color, and size. These can be used to customize the appearance of icons based on state.
6. Customizing Tab Bar Appearance
| Property | Description | Values | Notes |
|---|---|---|---|
| tabBarStyle | Style for the tab bar container | ViewStyle |
Accepts standard React Native view styles |
| tabBarActiveTintColor | Color of active tab icon and text | string |
Supports color names and hex values |
| tabBarInactiveTintColor | Color of inactive tab icon and text | string |
Defaults to system's inactive color |
| tabBarBackground | Background component for the tab bar | React.ComponentType |
Can be a custom component or View |
| tabBarLabelStyle | Style for the label text | TextStyle |
Applies to all labels in the tab bar |
| tabBarIndicatorStyle | Style for the active indicator | ViewStyle |
Customizes the underline or highlight |
Example: Customizing Tab Bar Appearance
import { createBottomTabNavigator } from '@react-navigation/bottom-tabs';
const Tab = createBottomTabNavigator();
function MyTabs() {
return (
<Tab.Navigator
screenOptions={{
tabBarStyle: { backgroundColor: '#f0f0f0' },
tabBarActiveTintColor: '#007AFF',
tabBarInactiveTintColor: '#8E8E93',
tabBarLabelStyle: { fontSize: 14 },
tabBarIndicatorStyle: { backgroundColor: '#007AFF' }
}}
>
<Tab.Screen name="Home" component={HomeScreen} />
<Tab.Screen name="Settings" component={SettingsScreen} />
</Tab.Navigator>
);
}
Note: The
tabBarStyle property accepts all standard React Native view styles, including backgroundColor, height, and borderTopWidth.
7. Implementing Drawer Content
Example: Basic Drawer Content Component
{`import React from 'react';
import { View, Text, TouchableOpacity, StyleSheet } from 'react-native';
const DrawerContent = ({ navigation }) => {
return (
<View style={styles.container}>
<TouchableOpacity
style={styles.item}
onPress={() => navigation.navigate('Home')}
>
<Text style={styles.text}>Home</Text>
</TouchableOpacity>
<TouchableOpacity
style={styles.item}
onPress={() => navigation.navigate('Profile')}
>
<Text style={styles.text}>Profile</Text>
</TouchableOpacity>
</View>
);
};
const styles = StyleSheet.create({
container: {
flex: 1,
paddingTop: 20,
},
item: {
paddingVertical: 15,
paddingHorizontal: 20,
},
text: {
fontSize: 16,
},
});
export default DrawerContent;`}
| Property | Description | Values |
|---|---|---|
| navigation | Navigation object provided by React Navigation | object |
| onPress | Function to handle item press | function |
Note: The Drawer Content component is passed as a prop to the
DrawerContentComponent in the Drawer Navigator configuration.
8. Handling Navigation State Persistence
Example: Using AsyncStorage for Navigation State
import AsyncStorage from '@react-native-async-storage/async-storage';
import { NavigationContainer } from '@react-navigation/native';
const restoreState = async () => {
try {
const savedState = await AsyncStorage.getItem('navigationState');
return savedState ? JSON.parse(savedState) : undefined;
} catch (error) {
console.error('Failed to restore navigation state:', error);
return undefined;
}
};
const saveState = async (state) => {
try {
await AsyncStorage.setItem('navigationState', JSON.stringify(state));
} catch (error) {
console.error('Failed to save navigation state:', error);
}
};
<NavigationContainer
initialState={await restoreState()}
onStateChange={saveState}
>
<AppNavigator />
</NavigationContainer>
| Property | Description | Values | Notes |
|---|---|---|---|
| initialState | Initial navigation state to restore | object |
State object from storage or undefined |
| onStateChange | Callback when navigation state changes | function |
Function that saves the state to storage |
Note: The navigation state includes screen stack, tab index, and other navigation-related data. Ensure that sensitive data is not persisted.
Warning: Do not persist sensitive user data in navigation state. Use secure storage for sensitive information.
Best Practices for Navigation State Persistence
- Use
AsyncStorageorSecureStorefor persistent storage - Implement error handling for state restoration
- Validate stored state before restoring
- Avoid persisting sensitive user data in navigation state
9. Implementing Authentication Flows
Example: Setting up Auth Flow with Navigation
// App.js
import React from 'react';
import { NavigationContainer } from '@react-navigation/native';
import { createStackNavigator } from '@react-navigation/stack';
import LoginScreen from './screens/LoginScreen';
import HomeScreen from './screens/HomeScreen';
const Stack = createStackNavigator();
function App() {
return (
<NavigationContainer>
<Stack.Navigator>
<Stack.Screen name="Login" component={LoginScreen} />
<Stack.Screen name="Home" component={HomeScreen} />
</Stack.Navigator>
</NavigationContainer>
);
}
export default App;
| Property | Description | Default |
|---|---|---|
| initialRouteName | Name of the screen to start navigation from | 'Home' |
| screenOptions | Global options for all screens in navigator | {} |
| headerShown | Whether to show header in navigator | true |
Note: Use
navigation.navigate('ScreenName') to navigate between screens.
Example: Handling Login State
// LoginScreen.js
import React, { useState } from 'react';
import { View, TextInput, Button, Alert } from 'react-native';
const LoginScreen = ({ navigation }) => {
const [username, setUsername] = useState('');
const [password, setPassword] = useState('');
const handleLogin = () => {
if (username && password) {
// Simulate login
navigation.navigate('Home');
} else {
Alert.alert('Error', 'Please enter valid credentials');
}
};
return (
<View style={{ padding: 20 }}>
<TextInput
placeholder="Username"
value={username}
onChangeText={setUsername}
style={{ borderWidth: 1, padding: 10, marginBottom: 10 }}
/>
<TextInput
placeholder="Password"
value={password}
secureTextEntry
onChangeText={setPassword}
style={{ borderWidth: 1, padding: 10, marginBottom: 10 }}
/>
<Button title="Login" onPress={handleLogin} />
</View>
);
};
export default LoginScreen;
Example: Protecting Routes with Auth
// HomeScreen.js
import React from 'react';
import { View, Text, Button } from 'react-native';
const HomeScreen = ({ navigation }) => {
const handleLogout = () => {
// Clear auth state and navigate to login
navigation.navigate('Login');
};
return (
<View style={{ padding: 20 }}>
<Text>Welcome to Home Screen!</Text>
<Button title="Logout" onPress={handleLogout} />
</View>
);
};
export default HomeScreen;
10. Using Navigation TypeScript Types
Example: Defining Navigation Prop Types
import { NavigatorScreenParams } from '@react-navigation/native';
export type HomeStackParamList = {
Home: undefined;
Details: { id: string };
};
export type MainTabParamList = {
HomeStack: NavigatorScreenParams<HomeStackParamList>;
Settings: undefined;
};
export type RootParamList = {
MainTab: NavigatorScreenParams<MainTabParamList>;
Profile: undefined;
};
| Type | Description | Usage |
|---|---|---|
| NavigatorScreenParams | Helper type for nested navigators | NavigatorScreenParams<ParamList> |
| ParamList | Interface defining route parameters | Home: undefined; Details: { id: string } |
Note: Use
undefined for routes without parameters.Example: Using Navigation Prop
import { useNavigation } from '@react-navigation/native';
import type { NativeStackNavigationProp } from '@react-navigation/native-stack';
type NavigationProp = NativeStackNavigationProp<RootParamList>;
const MyComponent = () => {
const navigation = useNavigation<NavigationProp>();
const handlePress = () => {
navigation.navigate('Profile');
};
return <Button title="Go to Profile" onPress={handlePress} />;
};