mediumReact Native#7

Tab navigator with badges

Prompt

Create a bottom tab navigator with two tabs: Home and Notifications. Show a badge count of 3 on the Notifications tab using the built-in badge option.

Solution

const Tab = createBottomTabNavigator()
function HomeScreen() { return <Text>Home</Text> }
function NotificationsScreen() { return <Text>Notifications</Text> }
export default function App() {
  return (
    <NavigationContainer>
      <Tab.Navigator>
        <Tab.Screen name="Home" component={HomeScreen} />
        <Tab.Screen
          name="Notifications"
          component={NotificationsScreen}
          options={{ tabBarBadge: 3 }}
        />
      </Tab.Navigator>
    </NavigationContainer>
  )
}
Mentor's take

Tab navigators encode a UX contract stacks don't: each tab keeps its own navigation state alive, so switching tabs preserves scroll position and in-progress input — tabs are siblings, not a history. That's why the standard architecture nests a stack inside each tab rather than mixing peers and pushes in one navigator.

The badge is the API-knowledge check. tabBarBadge is a first-class screen option — pass a number or string and React Navigation renders a correctly positioned, platform-styled badge, handling RTL layouts and font scaling. The per-screen options prop is the right placement for screen-specific config; screenOptions on the navigator is for defaults shared by every tab (icons, colors). In production the 3 comes from state: compute the unread count with a selector and pass options={{ tabBarBadge: unread || undefined }}undefined hides the badge, 0 would render a "0".

Red flag: hand-rolling a badge with an absolutely-positioned View over a tab icon. It breaks on RTL, font scaling, and every navigator update — reinventing a first-class option signals you didn't read the API surface before building.

Say it: "Tabs preserve per-tab state so I nest a stack inside each tab, and badges are the built-in tabBarBadge option driven by state — undefined to hide, never a hand-positioned View."