1

So, I'm trying to use React Navigation and I want to use the same Header component across all my screens.

I used the expo-cli to create the project.

In my MainTabNavigator.js file, I have a HomeStack and SettingsStack, and they look like this:

const config = Platform.select({
  web: { headerMode: "screen" },
  default: {}
});

const HomeStack = createStackNavigator(
  {
    Home: HomeScreen
  },
  config
);

HomeStack.navigationOptions = {
  tabBarIcon: ({ focused }) => (
    <NavButton
      focused={focused}
      name={focused ? "star" : "create"}
      label={focused ? "Save" : "New"}
    />
  )
};

HomeStack.path = "";

At the bottom of the file, I have my tabNavigator

const tabNavigator = createBottomTabNavigator(
  {
    HomeStack,
    SettingsStack
  },
  {
    tabBarOptions: {
      inactiveTintColor: "#fff",
      labelStyle: {
        fontSize: 14
      },
      showLabel: false,
      style: {
        backgroundColor: "#fff",
        borderTopColor: "#fff",
        height: 70,
        paddingBottom: 10,
        paddingTop: 10
      }
    }
  }
);

tabNavigator.path = "";

export default tabNavigator;

I tried adding a <Header /> component in the navigatorOptions and defaultNavigationOption above the tabBarOptions in the createBottomTabNavigator function.

Similar to this:

...
  {
    navigationOptions: {
      header: <Header />
    },
    tabBarOptions: {
      inactiveTintColor: "#fff",
      labelStyle: {
        fontSize: 14
      },
 ...

but this just gives me a blank header... not using my component.

I currently have the functionality I want, but I have to go into each Screen file and add:

HomeScreen.navigationOptions = {
  header: <Header />
};

Currently using "react-navigation": "^3.11.0"

Any help is appreciated!

4 Answers 4

5

This is how I'm achieving this. Create a CustomHeader component like this:

const MyHeader = (navigation) => {
return {
    header: props => <MyCustomHeader {...props} />,
    headerStyle: { backgroundColor: '#fff' },
    headerTintColor: '#000',
};
}

Then include it in defaultNavigationOptions in your stack navigator

const AppNavigator = createStackNavigator(
{
    Launch: {
        screen: LaunchComponent,
    }
},
{
    initialRouteName: "Launch",
    defaultNavigationOptions: ({ navigation }) => {
        return MyHeader(navigation)
    }
}
)
Sign up to request clarification or add additional context in comments.

4 Comments

Hey thanks Hamza, I used your answer to get something working. It's essentially the same thing, but, as I have multiple createStackNavigator calls, I just added your suggestion to a config object and added the config to each method call. I will post answer here as well that covers my unique specifics.
Could you add some explanation about why this works?
Hey Daltron, React official docs explained this very well. Go through it once, it will be a great investment of time. reactnavigation.org/docs/en/…
return keyword is what's missing for me
1

I wanted to achieve similar solution for DrawerNavigator. The only way to do this was to create HOC component.

import React, {Fragment} from 'react';

const NavHeader = props => {
 // ... NavHeader code goes here 
};

export const withHeader = Component => {
  return props => {
    return (
      <Fragment>
        <NavHeader {...props} />
        <Component {...props} />
      </Fragment>
    );
  };
};

Then in your Drawer you do:

<Drawer.Navigator>
    <Drawer.Screen
      name={ROUTES.DASHBOARD}
      component={withHeader(DashboardContainer)} // <--- Wrap it around component here.
    />
</Drawer.Navigator>

Comments

0

Set your StackNavigator as parent of your BottomTabNavigator, doing it will let you have a single header for all the bottomTabs. If you use this approach, and need for some reason to have a backButton on your header you have to change it manually yourself.

const bottomTabNavigator = createBottomTabNavigator(bottomRoutesConfig, bottomNavigatorConfigs)

createStackNavigator:({ tabNavigator : bottomTabNavigator },{ defaultNavigationOptions :{ header : <Header/> }})

Doing this you can use one global header for all the screens, but as said, to change something on the header based off the screen you have to change it yourself, making the header know in what location the user currently is.

Comments

-1

set header to null in every screen and load your component on each screens

class HomeScreen extends Component {
    static navigationOptions = {
        header: null,
    };

    render(){
    return(
      <View style={{flex:1}}>
          <Header />
      </View>
     )
   }
}

so, the default header of react-navigation will be null and you can load your custom component as header

OR

class HomeScreen extends React.Component {
  static navigationOptions = {
    // headerTitle instead of title
    headerTitle: <Header />,
  };

  /* render function, etc */
}

use headerTitle instead of title to load your custom component

1 Comment

drawback of this method is that you dont have access to the navigation prop inside your header - this prevents you to do back action

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.