2

Is it possible to have a custom header if I set the header to be off in React-Navigation V5?

I tried to, but the headerLeft and headerRight seems to do nothing, for example, I have the following:

<Stack.Screen
  component={UploadStack}
  name="UploadStack"
  options={{ headerShown: false }}
/>

and then in my UploadStack, I have

<Stack.Navigator initialRouteName="TrackUploadSelectionScreen">
      <Stack.Screen
        name="AddToPlaylistScreen"
        component={AddToPlaylistScreen}
      />
      <Stack.Screen
        name="TrackUploadSelectionScreen"
        component={TrackUploadSelectionScreen}
        options={{
          title: t('general.selectToUpload'),
          headerLeft: () =>
            Platform.select({
              ios: () => (
                <NavigationHeader.TextButton
                  label={t('general.cancel')}
                  onPress={navigation.goBack()}
                />
              ),
              android: () => (
                <NavigationHeader.IconButton
                  iconName="times"
                  label={t('general.cancel')}
                  onPress={navigation.goBack()}
                />
              )
            })
        }}
      />
</Stack.Navigator>

but it isn't creating anything

2 Answers 2

8

The method I found that worked was adding a function that renders react elements to the header attribute on the Stack.Navigator component. This would allow it to appear for every Stack.Screen child element.

Example as shown,

<Stack.Navigator
  initialRouteName="Page1"
  screenOptions={{header: NavHeader}}
>
     <Stack.Screen name="Page1" component={Page1} />
     <Stack.Screen name="Page2" component={Page2} />
</Stack.Navigator>

The NavHeader component can be simple react element. In this example you would simply have it as a function.

function NavHeader() {
    return <View>...</View>;
}
Sign up to request clarification or add additional context in comments.

1 Comment

What about if this header should receive properties depending on the children? Should I set this component in every <Stack.Screen>? Or is there a way to pass those properties to the parent.
5

If you set headerShown to false everything you set for the headerLeft, headerRight and header properties is not going to be shown. So remove that line if you do want to set any of these properties.

Additionally if you want to have a custom header, instead of the default bar you can simple set the header property. Here is an example of a custom header where the bar is removed, but 2 very simple buttons are placed on the left and the right using flexbox.

// ...
<Stack.Screen
  options={{
    header: () => (
      <View
        style={{
          display: 'flex',
          flexDirection: 'row',
          justifyContent: 'space-between',
          height: 50,
        }}>
        <TouchableOpacity
          style={{ padding: 10 }}
          onPress={() => {
            alert('Left');
          }}>
          <Text>Left</Text>
        </TouchableOpacity>
        <TouchableOpacity
          style={{ padding: 10 }}
          onPress={() => {
            alert('Right');
          }}>
          <Text>Right</Text>
        </TouchableOpacity>
      </View>
    ),
  }}
  // Other props...
/>
// ...

You can adjust the styling and content to fit your needs.

2 Comments

Yeah but I want to disable the header the navigation comes with so I have to do the headerShown: false, right?
No, like I mentioned if you set headerShown to false you can't set a custom header, so you only set that if you don't want to show anything at all. If you want to have a custom header you provide one using the header prop to override the default one like I showed in the example.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.