iwantcoding.com
🔥 Daily 👥 Rooms 🏆 Top Log in Sign up

Tab Navigator

Bottom tabs are the iOS/Android navigation pattern for top-level destinations. createBottomTabNavigator ships from React Navigation; each tab maintains its own stack and state.

Bottom tabs + per-tab stacks

EXAMPLE
import { NavigationContainer } from '@react-navigation/native';
import { createBottomTabNavigator } from '@react-navigation/bottom-tabs';
import { createNativeStackNavigator } from '@react-navigation/native-stack';
import { Ionicons } from '@expo/vector-icons';

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

// Per-tab stack — each tab is its own navigation history
function FeedStack() {
    return (
        <Stack.Navigator>
            <Stack.Screen name="FeedHome" component={Feed}   options={{ title: 'Feed' }} />
            <Stack.Screen name="Post"     component={Post}    options={({ route }) => ({ title: route.params.title })} />
        </Stack.Navigator>
    );
}

function ProfileStack() {
    return (
        <Stack.Navigator>
            <Stack.Screen name="ProfileHome" component={Profile} options={{ title: 'Profile' }} />
            <Stack.Screen name="Edit"        component={EditProfile} />
        </Stack.Navigator>
    );
}

export default function App() {
    return (
        <NavigationContainer>
            <Tab.Navigator
                screenOptions={({ route }) => ({
                    headerShown: false,
                    tabBarActiveTintColor: '#04AA6D',
                    tabBarIcon: ({ focused, color, size }) => {
                        const map = { Feed: 'home', Search: 'search', Profile: 'person' };
                        const base = map[route.name];
                        return <Ionicons name={focused ? base : \`${base}-outline\`} size={size} color={color} />;
                    },
                })}
            >
                <Tab.Screen name="Feed"    component={FeedStack} />
                <Tab.Screen name="Search" component={SearchStack}
                    options={{ tabBarBadge: 3 }} />        {/* notification badge */}
                <Tab.Screen name="Profile" component={ProfileStack} />
            </Tab.Navigator>
        </NavigationContainer>
    );
}

// Tap tab twice → pop to root
<Tab.Screen
    name="Feed"
    component={FeedStack}
    listeners={({ navigation }) => ({
        tabPress: (e) => {
            const state = navigation.getState();
            const tab   = state.routes[state.index];
            if (tab.name === 'Feed' && tab.state?.index > 0) {
                e.preventDefault();
                navigation.navigate('Feed', { screen: 'FeedHome' });
            }
        },
    })}
/>

Why it matters

Each tab gets its own Stack. Switching tabs preserves scroll position, form state, and history — the platform-native default users expect.

Tip: Tweak the snippet with Try it Yourself », then sit the quiz at the bottom of the page.

Example

Example
import { createBottomTabNavigator } from '@react-navigation/bottom-tabs';
const Tab = createBottomTabNavigator();
<Tab.Navigator>
    <Tab.Screen name="Feed" component={Feed} />
    <Tab.Screen name="Me" component={Me} />
</Tab.Navigator>
Try it Yourself »

Discussion

Loading…