Skip to content

Critical issues with Native Bottom Tab Navigator on Android #12963

@yagcismail

Description

@yagcismail

Current behavior

When using the native bottom tab navigator (createNativeBottomTabNavigator from @react-navigation/bottom-tabs/unstable) on Android with React Navigation 7.x, three critical bugs make the navigator unusable in production:

Issue 1: Blank/White Screen After Returning from Outer Stack Navigation (Old Architecture)

What Happens:
When navigating from any bottom tab to a screen outside the tab navigator (e.g., a modal, settings screen, or any screen in the root stack) and then returning via back button or navigation.goBack(), all tab content disappears. The bottom tab bar remains visible, but every tab shows a completely blank/white screen. The app appears frozen from the user's perspective.

Steps to Reproduce:

  1. Set up a native bottom tab navigator with nested stack navigators
  2. Create a root stack that contains the bottom tab navigator and an outer screen
  3. Navigate from any tab to the outer screen using navigation.navigate('OuterScreen')
  4. Press the hardware back button or call navigation.goBack()
  5. Result: All tabs show blank screens

Root Cause:
In TabsHost.kt, the onAttachedToWindow() method only updates the container when IS_NEW_ARCHITECTURE_ENABLED is true. When the parent ScreenFragment is recreated during outer stack navigation, the old architecture doesn't restore tab fragments properly.


Issue 2: Tab Content Disappears When Switching Between Tabs After Deep Navigation

What Happens:
After navigating 2-3 levels deep into a tab's stack (e.g., ScreenA → ScreenA1 → ScreenA2) and then switching to another tab via the tab bar, when you return to the original tab, the screen content is blank. The header may still render, but the screen body is completely empty.

Steps to Reproduce:

  1. Create bottom tabs with nested stacks containing multiple screens
  2. Navigate deep into one tab: navigation.navigate('ScreenA1')navigation.navigate('ScreenA2')
  3. Tap another tab in the tab bar to switch tabs
  4. Tap back to the original tab
  5. Result: Screen content is missing, only header visible (if any)

Root Cause:
In TabsHost.kt, the nativeFocusChange() method has an early return when newFocusedTab === oldFocusedTab. However, after parent fragment recreation, the fragment might be the same instance but its view is not properly attached to contentView. The early return prevents re-attachment.


Issue 3: ScrollView Content Hidden Under Native Tab Bar (No Automatic Padding)

What Happens:
Unlike React Navigation's JavaScript bottom tabs, the native bottom tab bar doesn't provide automatic bottom padding. When scrolling to the bottom of a ScrollView, FlatList, or any scrollable content, the last ~56dp (Material Design bottom navigation height) is hidden behind the tab bar and cannot be reached by the user.

Steps to Reproduce:

  1. Create a screen with long scrollable content inside a bottom tab
  2. Scroll to the very bottom
  3. Result: Last portion of content is unreachable, hidden under tab bar

Root Cause:

  • React Navigation's JavaScript tabs use BottomTabBarHeightContext with the useBottomTabBarHeight() hook
  • Native bottom tab bar doesn't emit height events to JavaScript
  • The context remains undefined, so automatic padding isn't applied to scrollable components

Testing Details:

  • Reproduction rate: 100% (consistently reproducible)
  • Tested on: Physical Android devices (API 30-35) and Android Emulators
  • Architecture: Issues 1 & 2 primarily affect Old Architecture; Issue 3 affects both architectures
  • All issues occur when using nested stack navigators inside bottom tabs with multi-level navigation

Expected behavior

  1. Tab Content Restoration: After navigating to outer stack screens and returning, all tab content should be restored and visible. The navigation state should be preserved and screens should render correctly.

  2. Maintained Navigation State: Switching between tabs should maintain each tab's navigation stack. Deep navigation states should persist and render properly when returning to a previously visited tab.

  3. Automatic Content Padding: ScrollView and FlatList content should automatically have bottom padding equal to the tab bar height (~56dp), similar to React Navigation's JavaScript bottom tabs. All content should be scrollable and visible without manual padding adjustments.

The native bottom tab navigator should provide the same reliability and UX as JavaScript bottom tabs, with better performance due to native rendering.

Reproduction

https://github.com/yagcismail/navigation-bottom-tab-bug

Platform

  • Android
  • iOS
  • Web
  • Windows
  • MacOS

Packages

  • @react-navigation/bottom-tabs
  • @react-navigation/drawer
  • @react-navigation/material-top-tabs
  • @react-navigation/stack
  • @react-navigation/native-stack
  • react-native-drawer-layout
  • react-native-tab-view

Environment

package version
@react-navigation/native 7.1.28
@react-navigation/bottom-tabs 7.10.0
@react-navigation/drawer 7.7.13
@react-navigation/stack 7.6.16
@react-navigation/native-stack 7.10.1
react-native-screens 4.18.0
react-native-safe-area-context 5.4.0
react-native-gesture-handler 2.25.0
react-native-reanimated 3.17.4
react-native-pager-view 6.7.0
react-native 0.79.3
expo 53.0.25
node 18
yarn -

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions