How to disable headers of a parent stack navigator from a screen of the child navigator in React Native?

Viewed 435

I am building a React Native app, I am using React Navigation and I have to disable headers of the parent navigator from the screen of a child navigator, so for example

  Tab Naviagtor A (Headers ON)
    Stack Navigator B (Headers OFF)
      Navigtor B Screens ( A, B, C, D, E)

So how do I disable the headers at Tab Navigator A, From a specific Navigator A Screen like C. So that When I navigate to Screen C I no more see the header but will be able to see the header on other screens like E and D.

4 Answers

This should be achievable by using route param like this on the Tab navigator:

<Tab.Navigator
      initialRouteName={"A")}
      screenOptions={({route}) => {
        return {
          headerShown: route.name !== "C",
        };
      }}>

Another option would be to hide the Tab Navigator header and enable Stack Navigator headers on those screens you need.

const StackNavigator = ({ navigation }) => {
  return (
    <Stack.Navigator
      screenOptions={{ headerShown: false }}

    >
      <Stack.Screen
        name="Tabs"
        component={TabNavigator}
        options={({ route }) => ({
          headerTitle: getHeaderTitle(route),
          headerLeft: () => (
            <NavigationHeaderDashboard navigationProps={navigation} position={'Right'} />
          ),
          headerStyle: {
            backgroundColor: '#FFFFFF',
          },
          headerTintColor: '#092241',
          headerTitleStyle: {
            fontWeight: 'bold',
            fontSize: 20,
            alignSelf: 'center',
          },
          headerTitleAlign: "center",
        })}

      />
      <Stack.Screen name="ViewScreen" component={ViewScreen} /> 
    </Stack.Navigator>

  );
};

I have Drawer (headers ON) -> Tab (headers OFF) -> Screen A, Screen B, Screen C, and I want to hide the drawer header in Screen C. This is how I solved the issue.

  1. Set an id on the drawer navigator
<Drawer.Navigator
  id='Drawer' // --> 1.
  screenOptions: {{...}}
>
  ...
</Drawer.Navigator>
  1. In Tab.Screen of C set "unmountOnBlur" to true
<Tab.Navigator
   screenOptions={{
     headerShown: false,
   }}
>
  // Other screens ...
  <Tab.Screen 
     name='C'
     component={ScreenC}
     options={{
       unmountOnBlur: true, // --> 2.
     }}
  />
</Tab.Navigator>
  1. In the Screen C component, get the parent navigator (drawer) and set screen options "headerShown: false"
export default function ScreenC({ navigation, route }) {
  React.useLayoutEffect(() => {
    if (!navigation || !route) return

    // Get parent by id
    const drawerNavigator = navigation.getParent('Drawer')

    if (drawerNavigator) {
      // Make sure the route name is C before turn header off
      if (route.name === 'C') { 
        drawerNavigator.setOptions({
          headerShown: false,
        })
      }
    }

    // Turn header back on when unmount
    return drawerNavigator
      ? () => {
          drawerNavigator.setOptions({
            headerShown: true,
          })
        }
      : undefined
  }, [navigation, route])

   return ...
}

Hope this help

V0.6

In your Navigtor B Screens, do:

import { useFocusEffect } from '@react-navigation/native';

useFocusEffect(
        useCallback(() => {
        // Do something when the screen is focused
        props.navigation.getParent().setOptions({ headerShown: false})
        return () => {
            // Do something when the screen is unfocused
            // Useful for cleanup functions
            props.navigation.getParent().setOptions({ headerShown: true})
        };
        }, [])
    )
Related