Onyx
Onyx

Reputation: 5772

How to conditionally render headerLeft using React Native navigation?

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 Test 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="Test"
            options={{ title: 'test', headerBackVisible: false }}
            component={Test}
        />

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

const TestStack: FunctionComponent = () => {
    const navigation = useNavigation();

    const headerTitle = <Text>Log in</Text>;

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

Upvotes: 0

Views: 1045

Answers (2)

A G
A G

Reputation: 22559

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>
  );
}

Upvotes: 1

David Scholz
David Scholz

Reputation: 9733

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])
}

Upvotes: 0

Related Questions