'React Navigation v5 use custom header

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



Solution 1:[1]

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.

Solution 2:[2]

Old thread, however I ran into a similar question. 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>;
}

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1
Solution 2 Sam Chowdhury