verybaddeveloper
verybaddeveloper

Reputation: 269

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

Upvotes: 2

Views: 18583

Answers (2)

Sam Chowdhury
Sam Chowdhury

Reputation: 81

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

Upvotes: 8

bas
bas

Reputation: 15462

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.

Upvotes: 5

Related Questions