Skip to main content

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 AsyncStorage or SecureStore for 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} />;
};

Was this article helpful?