On attempt to stylize the header still can't change the height that is on the header
Even using
static navigationOptions = ({navigation}) => ({
title: 'Title',
headerStyle: {height: 60}
})
I prefer to remove entirely the header, and then I used a header from react-native-elements:
createStackNavigator(screens, { headerMode: 'none' })
And then, the Header
import { Header } from 'react-native-elements';
<Header...>
That component consider the top status bar size, and do all things automatically, and run on Expo and ejected apps
Related
Current behavior
In my team we would like to upgrade react navigation to V5. Since our codebase is very large we have to do an incremental refactor (Upgrading everything in one shot is impossible).
For this reason we would like to use the helper #react-navigation/compat with the latest version ^5.3.20. So far this is the different piece of code we have updated:
Main app navigation:
At start we were using createSwitchNavigator. At startup we check if user is logged in:
If yes: redirect to MainNavigation navigator.
if no: redirect to Authentification navigator.
<NavigationContainer>
<Main.Navigator>
<Main.Screen
name={SceneKeys.Startup}
component={Startup}
options={{ header: () => null }}
></Main.Screen>
{ !authenticated ? (
<Main.Screen
name={SceneKeys.Authentication}
component={AuthenticationNavigation}
options={{ header: () => null }}
></Main.Screen>
) : (
<Main.Screen
name={SceneKeys.App}
component={MainNavigation}
options={{ header: () => null }}
></Main.Screen>
)}
</Main.Navigator>
</NavigationContainer>
This part work well, if user is not logged in we are correctly redirected to AuthenticationNavigation. The problem is in our main navigation.
const MainNavigation = createCompatNavigatorFactory(createStackNavigator)(
{
// Main stack contain many navigator (switch, drawer, etc...)
MainStack: { screen: TabBarNavigator, navigationOptions: { header: null } },
// ...other routes
}
When we redirect on this navigator we have some errors coming from withNavigation (in compat mode) and navigationOptions.
withNavigation:
The error say that we cannot use withNavigation since it's a hook and we can only call this in the body of a function. However we use the compat' mode and on the doc it says that is exported as a HOC.
export default withNavigation(
connect(mapStateToProps, mapDispatchToProps)(OurComponent),
);
Header:
Header props fail even with the compat' mode with navigationOptions and createCompatNavigatorFactory
const MessagingNavigator = createCompatNavigatorFactory(createStackNavigator)(
{
[SceneKeys.messaging]: {
screen: Messaging,
navigationOptions: ({ navigation }) => ({
header: (
<MessagingNavBar mode={'conversationsList'} navigation={navigation} />
),
drawerLockMode: navigation.state.params
? navigation.state.params.drawerLockMode
: undefined,
}),
},
If I delete navigationOptions property and I refactor withNavigation by using useNavigation() hook it works well and go to the correct screen otherwise it doesn't work.
At the moment we cannot afford to refactor everything from the ground up and we would like to do that incrementally. With the informations above, did we miss something ?
Expected behavior
Is withNavigation should work as an HOC's with component and redux-connect since it's exported from compat' plugin ?
Why navigationOptions not working with the previous headers implementation in compatibility mode?
In the new version i.e, the 0.61 of react-native, I didn't find any sort of mechanism for changing the font of the title. The earlier versions have their own solutions but the present one doesn't have one, which in turn prompted me to ask the question. How do you change the font?
if you use for navigation in "reactnavigation" library
Do it that way
As described in the documentation
class HomeScreen extends React.Component {
static navigationOptions = {
title: 'Home',
headerStyle: {
backgroundColor: '#f4511e',
},
headerTintColor: '#fff',
headerTitleStyle: {
fontWeight: 'bold',
},
};
/* render function, etc */
}
Background
While building a React Native application and using a DrawerNavigator from React Navigation I ended up needing to customize the header that comes with a createDrawerNavigator. I found that I can customize a createStackNavigator though.
createStackNavigator
Can hide the header
Can customize the header.
createDrawerNavigator
Can NOT hide the header
Can NOT customize the header.
Question
How do I hide or customize the header that automatically is added to my app when using the createDrawerNavigator from React Navigation?
Example
createStackNavigator
I can hide the header that appears when using createStackNavigator like this,
const Secure = createStackNavigator(
{
Drawer: {
screen: drawer,
},
},
{
initialRouteName: 'Drawer',
headerMode: 'none',
},
);
createDrawerNavigator
When using createDrawerNavigator nothing I try works to hide or customize the header. I have also searched the documentation and can not find anything referencing how to deal with the header in React Native navigation Version 3 for createDrawerNavigator.
This code will be help the header none for custom drawer component.
const customDrawerContentComponent = (props) => {
Contact: {
screen: ContactScreen ,
navigationOptions: () => ({
header: null
})
}
}
const AppDrawerNavigator = createDrawerNavigator({
Home: {
screen: HomeScreen,
navigationOptions: () => ({
header: null
})
}
}, {
contentComponent: customDrawerContentComponent,
})
Like the answer from Kazi said, you can pass headerMode: null to hide the header from the drawerNavigators and the stacknavigator. The problem with this is that you end up with no headers at all.
So if you want headers for specific screens, there's a header component on react-native-elements that you can add to each screen you want a header on.
Here's an example:
<React.Fragment>
<Header
statusBarProps={{ barStyle: 'light-content' }}
barStyle="light-content"
leftComponent={
<SimpleIcon
name="menu"
color="#34495e"
size={20}
/>
}
centerComponent={{ text: 'HOME', style: { color: '#34495e' } }}
containerStyle={{
backgroundColor: 'white',
justifyContent: 'space-around',
}}
/>
</React.Fragment>
In this example, I had to wrap it on React.Fragment tags because I put this part of the code in the beginning of the render method. I also added a title to the screen and the hamburguer button to open the drawer.
So, basically what I did is, hide the header on both stackNavigators and drawerNavigators then add the component to each of your screens that you do want a header on.
I am using react-native-navigation and trying to create a DrawerNavigator which does not unmount the previously opened screens just like how TabNavigator works. Because one of my screens contains a webview and I do not want it to reload everytime I change screens.
Here is some sample code in App.js..
const Drawer = DrawerNavigator(
{
Home: { screen: Home },
PageWithWebview: { screen: PageWithWebview},
Settings: { screen: Settings },
},
{
initialRouteName: "Home",
contentComponent: props => <SideBar user={global.user} />
}
);
const AppNavigator = StackNavigator(
{
Drawer: { screen: Drawer },
},
{
initialRouteName: "Drawer",
headerMode: "none"
}
);
export default () =>
<Root>
<AppNavigator/>
</Root>;
And in my Sidebar component I have buttons to navigate to a different route depending on what is selected .
onPress={() => this.props.navigation.navigate(selected, { userDetails: global.user })}
In the later versions of react native navigation they added the unmountInactiveScreens property for the DrawerNavigator
unmountInactiveScreens
Whether a screen should be unmounted when navigating away from it. Unmounting a screen resets any local state in the screen as well as state of nested navigators in the screen. Defaults to false.
I'm using the official react-navigation to handle my navigation. I have one main TabNavigator for the whole app with two tabs (called HitchhikingMapNavigator and SettingsNavigator below), and each tab has a nested StackNavigator:
const HitchhikingMapNavigator = StackNavigator({
hitchhikingMap: { screen: HitchhikingMapViewContainer },
spotDetails: { screen: SpotDetailsViewContainer }
}, {
navigationOptions: {
header: {
visible: false
}
}
});
const SettingsNavigator = StackNavigator({
// some other routes
});
export default AppNavigator = TabNavigator({
hitchhikingMap: { screen: HitchhikingMapNavigator },
settings: { screen: SettingsNavigator }
}, {
navigationOptions: {
header: {
visible: false,
},
},
});
As you can see, I put the headers' visilibility to false everywhere, even in my HitchhikingMapViewContainer's view:
class HitchhikingMapView extends React.Component {
static navigationOptions = {
title: 'Map',
header: {
visible: false,
},
//...other options
}
And yet, the header bar is still visible:
If I don't nest the navigators (i.e. if I put this code, skipping the nested one):
export default AppNavigator = TabNavigator({
hitchhikingMap: { screen: HitchhikingMapViewContainer },
settings: { screen: SettingsNavigator }
});
then the header is correctly hidden.
So conclusion: I can't make a header not visible when I have two nested navigators. Any ideas?
For those who are still looking for the answer, I will post it here.
So two solutions:
1st solution: use headerMode: 'none' in the StackNavigator. This will remove the header from ALL screens in the StackNavigator
2nd solution: use headerMode: 'screen' in the StackNavigator and add header: { visible: false } in the navigationOptions of the screens where you want to hide the header.
More info can be found here: https://reactnavigation.org/docs/en/stack-navigator.html
Starting from v1.0.0-beta.9, use the following,
static navigationOptions = {
header: null
}
This worked for me:
headerMode: 'none'
This works for me to hide the navigation:
static navigationOptions = {
header: null
};
This Worked for me, i am working on android side in react native version 0.45
static navigationOptions = {
header: null
}