0
0
React Nativemobile~7 mins

Custom tab bars in React Native

Choose your learning style9 modes available
Introduction

Custom tab bars let you change how the bottom navigation looks and works in your app. This helps make your app unique and easier to use.

You want to add icons and text with special colors in your app's bottom tabs.
You want to change the shape or style of the tab bar to match your brand.
You want to add animations or badges on tabs to show notifications.
You want to control what happens when a tab is pressed, like showing a message.
You want to hide or show the tab bar on certain screens.
Syntax
React Native
function MyTabBar({ state, descriptors, navigation }) {
  return (
    <View style={{ flexDirection: 'row' }}>
      {state.routes.map((route, index) => {
        const isFocused = state.index === index;
        const onPress = () => {
          const event = navigation.emit({
            type: 'tabPress',
            target: route.key,
            canPreventDefault: true
          });
          if (!isFocused && !event.defaultPrevented) {
            navigation.navigate(route.name);
          }
        };
        return (
          <TouchableOpacity
            key={route.key}
            onPress={onPress}
            style={{ flex: 1, padding: 10, backgroundColor: isFocused ? '#ddd' : '#fff' }}
          >
            <Text>{route.name}</Text>
          </TouchableOpacity>
        );
      })}
    </View>
  );
}

The state object tells which tab is active and the list of tabs.

The navigation object lets you move between tabs.

Examples
A very simple tab bar with just text buttons for each tab.
React Native
function SimpleTabBar({ state, navigation }) {
  return (
    <View style={{ flexDirection: 'row' }}>
      {state.routes.map((route, index) => (
        <TouchableOpacity
          key={route.key}
          onPress={() => navigation.navigate(route.name)}
          style={{ flex: 1, padding: 10 }}
        >
          <Text>{route.name}</Text>
        </TouchableOpacity>
      ))}
    </View>
  );
}
This tab bar changes background and text color for the active tab.
React Native
function ColoredTabBar({ state, navigation }) {
  return (
    <View style={{ flexDirection: 'row' }}>
      {state.routes.map((route, index) => {
        const isFocused = state.index === index;
        return (
          <TouchableOpacity
            key={route.key}
            onPress={() => navigation.navigate(route.name)}
            style={{
              flex: 1,
              padding: 10,
              backgroundColor: isFocused ? 'skyblue' : 'white'
            }}
          >
            <Text style={{ color: isFocused ? 'white' : 'black' }}>{route.name}</Text>
          </TouchableOpacity>
        );
      })}
    </View>
  );
}
Sample App

This app shows two tabs: Home and Settings. The custom tab bar changes the background color of the active tab to purple and text to white. Other tabs have white background and black text.

React Native
import React from 'react';
import { View, Text, TouchableOpacity } from 'react-native';
import { NavigationContainer } from '@react-navigation/native';
import { createBottomTabNavigator } from '@react-navigation/bottom-tabs';

function HomeScreen() {
  return <View style={{ flex: 1, justifyContent: 'center', alignItems: 'center' }}><Text>Home Screen</Text></View>;
}

function SettingsScreen() {
  return <View style={{ flex: 1, justifyContent: 'center', alignItems: 'center' }}><Text>Settings Screen</Text></View>;
}

function MyTabBar({ state, descriptors, navigation }) {
  return (
    <View style={{ flexDirection: 'row', backgroundColor: '#eee' }}>
      {state.routes.map((route, index) => {
        const isFocused = state.index === index;
        const onPress = () => {
          const event = navigation.emit({ type: 'tabPress', target: route.key, canPreventDefault: true });
          if (!isFocused && !event.defaultPrevented) {
            navigation.navigate(route.name);
          }
        };
        return (
          <TouchableOpacity
            key={route.key}
            onPress={onPress}
            style={{ flex: 1, padding: 15, backgroundColor: isFocused ? '#6200ee' : '#fff' }}
            accessibilityRole="button"
            accessibilityState={isFocused ? { selected: true } : {}}
            accessibilityLabel={descriptors[route.key].options.tabBarAccessibilityLabel}
            testID={descriptors[route.key].options.tabBarTestID}
          >
            <Text style={{ color: isFocused ? 'white' : 'black', textAlign: 'center' }}>{route.name}</Text>
          </TouchableOpacity>
        );
      })}
    </View>
  );
}

const Tab = createBottomTabNavigator();

export default function App() {
  return (
    <NavigationContainer>
      <Tab.Navigator tabBar={props => <MyTabBar {...props} />}>
        <Tab.Screen name="Home" component={HomeScreen} />
        <Tab.Screen name="Settings" component={SettingsScreen} />
      </Tab.Navigator>
    </NavigationContainer>
  );
}
OutputSuccess
Important Notes

Always add accessibility props like accessibilityRole and accessibilityState for better screen reader support.

You can add icons or badges inside the tab buttons to improve UI.

Remember to handle the tabPress event to allow default navigation behavior.

Summary

Custom tab bars let you design your own bottom navigation look and feel.

You get the current tab info from state and control navigation with navigation.

Use TouchableOpacity or similar to make tabs clickable.