Skip to content

SafeAreaProvider returns device-only insets for pre-rendered tabs in NativeTabs #3573

@marcospgp

Description

@marcospgp

Context

When using expo-router's NativeTabs (which uses react-native-screens), all tabs are pre-rendered before the tab bar is measured. This causes nested SafeAreaProviders to return device-only insets (~34px) instead of bounded insets (~83px including tab bar).

Related issues:

The Problem

  1. NativeTabs pre-renders all tabs simultaneously on app load
  2. Pre-rendered tab content doesn't appear to be positioned as a child of the tab bar layout in the native view hierarchy
  3. When a nested SafeAreaProvider measures, it gets device-only insets (container to screen edge)
  4. When user visits the tab, insets jump from 34px to 83px = visible layout flash

Question

Is there a mechanism in react-native-screens (or could there be) to:

  1. Ensure pre-rendered screens in a tab navigator are positioned relative to the tab bar from the start?
  2. Provide bounded insets for inactive/pre-rendered screens?
  3. Defer SafeAreaProvider measurement until the screen is correctly positioned?

Or is this purely an expo-router concern in how they use react-native-screens?

Workaround

We're currently sharing insets via React context across tab screens and caching the largest bottom value (which includes the tab bar). First tab visited still flashes, subsequent tabs use cached correct insets.

Environment

  • expo-router: 6.0.21
  • react-native-screens: (via expo)
  • react-native: 0.81.5
  • iOS 18

Metadata

Metadata

Assignees

No one assigned

    Labels

    Missing infoThe user didn't precise the problem enoughMissing reproThis issue need minimum repro scenarioPlatform: iOSThis issue is specific to iOSType: BugSomething isn't working

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions