Home > Enterprise >  How to conditionally render headerLeft using React Native navigation?
How to conditionally render headerLeft using React Native navigation?

Time:05-12

I have a component that returns a <Stack.Navigator> that contains a couple of screens. I also have a custom headerLeft element that executes a function on click. Now I am trying to hide the headerLeft if I am on the enterEmail screen, but have it visible on all the others.

Before implementing my own back button, I just used this to hide the back button on the enterEmail screen:

        <Stack.Screen
            name="EnterEmail"
            options={{ title: LOGIN_TITLE, headerBackVisible: false }}
            component={EnterEmail}
        />

But now that I'm using a custom element, this doesn't work.

const AuthStack: FunctionComponent = () => {
    const navigation = useNavigation<LandingScreenNavigationProp>();

    const headerTitle = <HeaderText variant="h5">Log in</HeaderText>;

    return (
        <Stack.Navigator
            initialRouteName="Landing"
            screenOptions={{
                animation: authStackAnimation,
                headerTitleAlign: 'center',
                headerBackVisible: false,
                headerLeft: () => <NavigationBackButton onPress={() => navigation.goBack()} />,
                headerRight: () => <NavigationCloseButton onPress={() => navigation.navigate('Landing')} />,
            }}
        >
            <Stack.Screen options={{ headerShown: false }} name="Landing" component={Landing} />
            <Stack.Screen name="EnterEmail" options={{ headerTitle: () => headerTitle }} component={EnterEmail} />
            <Stack.Screen name="EnterPassword" options={{ headerTitle: () => headerTitle }} component={EnterPassword} />
            <Stack.Screen name="EnterOTP" options={{ headerTitle: () => headerTitle }} component={EnterOTP} />
            <Stack.Screen
                name="CheckYourEmail"
                options={{ headerTitle: () => headerTitle }}
                component={CheckYourEmail}
            />
        </Stack.Navigator>
    );
};

CodePudding user response:

You can use a useLayoutEffect to remove the headerLeft button in your EnterEmail screen as follows.

const EnterEmail = ({navigation}) => {
  useLayoutEffect(() => {
    navigation.setOptions({
      headerLeft: () => null,
    })
  }, [navigation])
}

CodePudding user response:

You will need to override the group/navigator options in stack screens.

<Stack.Screen
  name="EnterEmail"
  options={{ 
    headerTitle: () => headerTitle,
    headerLeft: {} // hide the header
  }}
  component={EnterEmail}
/>

I've create a snack with logo & background at navigator level but the stack screen overrides it.

function App() {
  return (
    <NavigationContainer>
      <Stack.Navigator screenOptions={{
        headerStyle: { backgroundColor: 'papayawhip' },
        headerTitle: (props) => <LogoTitle {...props} />
        }}>
        <Stack.Screen
          name="Dashboard"
          component={Dashboard}
          options={{
          headerTitle: {}, // override
          headerStyle: { backgroundColor: 'red' } }} // override
        />
        <Stack.Screen
          name="Home"
          component={HomeScreen}
        />
      </Stack.Navigator>
    </NavigationContainer>
  );
}
  • Related