Search code examples
react-nativeheaderreact-navigation-stackstack-navigator

react-navigation/stack: header not showing in sub stack after clean build


Since doing a clean build of our app the headers of sub stacks don't show anymore. I assume the removal and recreation of the yarn.lock file updated some dependencies correctly, so we are no longer lingering on some old versions. I tried another explicit update of react-navigation/native and react-navigation/stack to the latest (currently 5.7.3 and 5.9.0), but to no avail.

Our navigation setup is one root stack with multiple sub stacks below that. The root stack is the main app navigation, like login and dashboard. The sub stacks are for blocks of functionality available via the dashboard, one each per block. The sub stack headers can vary in style and content.

I tried adjusting the Stack.Navigator headerMode or screenOptions and the Stack.Screen options, but I couldn't find a solution. So any help is appreciated.

A simplified version of the code showing the issue is this:

// Root navigation

enum RootRoutes {
    Login = 'Login',
    Dashboard = 'Dashboard',
    Sub = 'Sub',
}

type RootStackParamList = {
    [RootRoutes.Login]: undefined;
    [RootRoutes.Dashboard]: undefined;
    [RootRoutes.Sub]: undefined;
};

const RootStack = createStackNavigator<RootStackParamList>();

const RootStackNavigation = () => {
    return (
        <RootStack.Navigator
            headerMode='screen'
            initialRouteName={RootRoutes.Login}
            screenOptions={{
                headerStyle: {
                    elevation: 0,
                },
            }}
        >
            <RootStack.Screen
                component={LoginScreen}
                name={RootRoutes.Login}
            />
            <RootStack.Screen
                component={DashboardScreen}
                name={RootRoutes.Dashboard}
                options={{
                    title: 'Dashboard',
                }}
            />
            <RootStack.Screen
                component={SubStackNavigation}
                name={RootRoutes.Sub}
                options={{
                    header: () => null, // needed to hide the header on sub screens
                }}
            />
        </RootStack.Navigator>
    );
};


// Sub navigation

enum SubRoutes {
    Index = 'SubIndex',
}

type SubStackParamList = {
    [SubRoutes.Index]: undefined;
};

const SubStack = createStackNavigator<SubStackParamList>();

const SubStackNavigation = () => {
    return (
        <SubStack.Navigator
            headerMode='screen'
            initialRouteName={SubRoutes.Index}
            screenOptions={{
                headerTransparent: true,
            }}
        >
            <SubStack.Screen
                component={IndexScreen}
                name={SubRoutes.Index}
                options={{
                    title: 'Sub screen',
                }}
            />
        </SubStack.Navigator>
    );
};


// App.tsx

export const App = () => {
    return (
        <NavigationContainer><RootStackNavigation/></NavigationContainer>
    );
};

Only removing header: () => null made a difference, but this shows the root header, with incorrect styling and not the custom content (apart from title) and also navigating in the root stack alone.


Solution

  • Ok, this turned out to be a small difference in the latest react navigation version. Instead of hiding the root header for the sub stack with

    options={{
        header: () => null,
    }}
    

    in its Stack.Screen, it needs to be with

    options={{
        headerShown: false,
    }}