React Native course ยท Module 3: Navigation
Tab Navigation - Underwater Menu Tabs
In this lesson7
In the palace of Atlantis there is a main menu with tabs, allowing you to quickly move between the main sections. This is Tab Navigation!
Installing Tab Navigator
npx expo install @react-navigation/bottom-tabsBasic Tab Navigator
import { createBottomTabNavigator } from '@react-navigation/bottom-tabs';
import { Ionicons } from '@expo/vector-icons';
type TabParamList = {
Home: undefined;
Search: undefined;
Profile: undefined;
Settings: undefined;
};
const Tab = createBottomTabNavigator<TabParamList>();
function MainTabs() {
return (
<Tab.Navigator
screenOptions={({ route }) => ({
tabBarIcon: ({ focused, color, size }) => {
let iconName: keyof typeof Ionicons.glyphMap;
switch (route.name) {
case 'Home':
iconName = focused ? 'home' : 'home-outline';
break;
case 'Search':
iconName = focused ? 'search' : 'search-outline';
break;
case 'Profile':
iconName = focused ? 'person' : 'person-outline';
break;
case 'Settings':
iconName = focused ? 'settings' : 'settings-outline';
break;
default:
iconName = 'ellipse';
}
return <Ionicons name={iconName} size={size} color={color} />;
},
tabBarActiveTintColor: '#1a5276',
tabBarInactiveTintColor: 'gray',
})}
>
<Tab.Screen name="Home" component={HomeScreen} />
<Tab.Screen name="Search" component={SearchScreen} />
<Tab.Screen name="Profile" component={ProfileScreen} />
<Tab.Screen name="Settings" component={SettingsScreen} />
</Tab.Navigator>
);
}Styling the Tab Bar
<Tab.Navigator
screenOptions={{
tabBarStyle: {
backgroundColor: '#0a2e4a',
borderTopWidth: 0,
elevation: 10,
height: 60,
paddingBottom: 8,
paddingTop: 8,
},
tabBarActiveTintColor: '#00d4ff',
tabBarInactiveTintColor: '#6c7a89',
tabBarLabelStyle: {
fontSize: 12,
fontWeight: '600',
},
headerStyle: {
backgroundColor: '#0a2e4a',
},
headerTintColor: '#fff',
}}
>
{/* Screens */}
</Tab.Navigator>Badge on a Tab
<Tab.Screen
name="Notifications"
component={NotificationsScreen}
options={{
tabBarBadge: 3, // Shows a badge with a number
tabBarBadgeStyle: {
backgroundColor: '#ff6b6b',
color: '#fff',
},
}}
/>Hiding the Tab Bar on Certain Screens
// In the screen component
import { useLayoutEffect } from 'react';
function DetailsScreen({ navigation }) {
useLayoutEffect(() => {
navigation.getParent()?.setOptions({
tabBarStyle: { display: 'none' },
});
return () => {
navigation.getParent()?.setOptions({
tabBarStyle: { display: 'flex' },
});
};
}, [navigation]);
return <View>{/* content */}</View>;
}Nesting Stack in Tabs
// Each tab can have its own Stack Navigator
function HomeStack() {
return (
<Stack.Navigator>
<Stack.Screen name="HomeMain" component={HomeScreen} />
<Stack.Screen name="HomeDetails" component={DetailsScreen} />
</Stack.Navigator>
);
}
function App() {
return (
<NavigationContainer>
<Tab.Navigator>
<Tab.Screen
name="Home"
component={HomeStack}
options={{ headerShown: false }} // Hide Tab header, Stack has its own
/>
<Tab.Screen name="Profile" component={ProfileStack} />
</Tab.Navigator>
</NavigationContainer>
);
}Top Tabs (Material Top Tabs)
npx expo install @react-navigation/material-top-tabs react-native-pager-viewimport { createMaterialTopTabNavigator } from '@react-navigation/material-top-tabs';
const TopTab = createMaterialTopTabNavigator();
function ProfileTabs() {
return (
<TopTab.Navigator
screenOptions={{
tabBarLabelStyle: { fontSize: 14, fontWeight: 'bold' },
tabBarStyle: { backgroundColor: '#0a2e4a' },
tabBarActiveTintColor: '#00d4ff',
tabBarIndicatorStyle: { backgroundColor: '#00d4ff' },
}}
>
<TopTab.Screen name="Posts" component={PostsScreen} />
<TopTab.Screen name="Photos" component={PhotosScreen} />
<TopTab.Screen name="Likes" component={LikesScreen} />
</TopTab.Navigator>
);
}Tab Navigation is ideal for the main sections of an application. Users expect it at the bottom of the screen (iOS) or at the top (Android Material Design).
Code for this lesson: App.tsx
import React from 'react';
import { View, Text, StyleSheet } from 'react-native';
import { NavigationContainer } from '@react-navigation/native';
import { createBottomTabNavigator } from '@react-navigation/bottom-tabs';
import { Ionicons } from '@expo/vector-icons';
const Tab = createBottomTabNavigator();
function Screen({ label }) {
return (
<View style={styles.screen}>
<Text style={styles.title}>{label}</Text>
</View>
);
}
const HomeScreen = () => <Screen label="Main Hall" />;
const MapScreen = () => <Screen label="Map of the Depths" />;
const ProfileScreen = () => <Screen label="Triton's Profile" />;
export default function App() {
return (
<NavigationContainer>
<Tab.Navigator>
{/* TODO: add a "Home" tab with component={HomeScreen} */}
{/* In options set tabBarIcon: ({ color, size }) => <Ionicons name="home" size={size} color={color} /> */}
{/* TODO: add a "Map" tab (component={MapScreen}, icon "map") */}
{/* TODO: add a "Profile" tab (component={ProfileScreen}, icon "person") */}
</Tab.Navigator>
</NavigationContainer>
);
}
const styles = StyleSheet.create({
screen: {
flex: 1,
justifyContent: 'center',
alignItems: 'center',
backgroundColor: '#1a5276',
},
title: {
fontSize: 22,
color: '#fff',
fontWeight: '600',
},
});Docs entries used in this lesson
Spotted a mistake in this lesson?
Check yourself
Answer the questions from this lesson. Pick an answer to see right away whether it is correct.
1. Which library is used to create bottom tabs?
2. Which property adds a badge (notification count) on a tab?
These are 2 of 3 questions for this lesson. Solve the rest in the game.
Hands-on tasks in the game
- Horizontal ordering
Arrange the correct tabBarIcon structure:
- Code editor
Complete the Tab Navigator code.