Reputation: 81
I am creating a React Native app that's supposed to have a custom header for basically all screens, so I've made a Navbar component that I have set as a default header which works fine. Although when I navigate between screens in the app, the header is not transitioning as it is supposed to be. With a standard header, the old one fades out and the new one in when you navigate to another route in the stack, but mine just replaces itself automatically.
I believe the problem might revolve around that all screens have the "same" Navbar component, that is there is not a new one created for each screen, so when I navigate it just updates the props of the navbar and re-renders it.
Here is the navigator setup
App.js
...
const stackNavigator = createStackNavigator(
{
...
}, {
initialRouteName: "Home",
defaultNavigationOptions: ({ navigation }) => ({
header: (headerProps) => {
return <Navbar navigation={navigation} {...headerProps.scene.descriptor.options} /> //Will pass navigationOptions as props
},
animationEnabled: true
}),
navigationOptions: {
animationEnabled: true,
},
headerTransitionPreset: 'fade-in-place',
transitionConfig: () => {
return {
transitionSpec: {
duration: 2000, //Easier to see the navigation animation
}
}
}
);
The Navbar component is a regular React.Component, along with all other screen components if that makes any difference
Are there some kind of props I should take care of? I have search all over the web, especially on the React Navigation docs and API reference but have found no info.
Here are some examples of how it looks with my custom navbar and how it looks with the default header. Note that the default fades during the whole transition while my custom just switches view in an instance. The only change I made was comment out the header: ...
part
Custom https://i.sstatic.net/BdvoY.jpg
Default https://i.sstatic.net/2vnko.jpg
Upvotes: 5
Views: 3343
Reputation: 1943
I'm on [email protected]
and the following works for me (taken from my code):
<Stack.Navigator>
<Stack.Screen
name={"route1"}
component={Route1View}
options={{title: "route 1 title"}}
/>
<Stack.Screen
name={"route2}
component={Route2View}
options={({navigation, route}) =>({
title: "route 2 title",
header: (props) => <CustomHeader {...props} />
})}
/>
</Stack.Navigator>
If you start with route 1, the default header is shown. When you push route 2, the custom header will fade in. When you leave, the default will show once again.
Upvotes: 0
Reputation: 764
If I understood it correctly your header is not navigating with screen? If that is the case use headerMode='screen'
According to react-navigation 5.*
<NavigationContainer>
<Stack.Navigator initialRouteName="List" headerMode='screen'>
<Stack.Screen name="Article"
component= { Article }/>
<Stack.Screen name="List"
component= { List }/>
</Stack.Navigator>
</NavigationContainer>
header mode set to screen navigate the header with screen which is common in android where as if you set it to float header will not navigate but changes its content which is common in ios. set it to none if you dont want header.
Upvotes: 1
Reputation: 11703
You can specify any component for left and right in the header in the screen configuration, you can have something like this:
createStackNavigator({
home: {
screen: (props) => (
<View style={{flex: 1}}>
</View>
),
navigationOptions: () => ({
title: `Title`,
headerRight: (
<React.Fragment>
<Button title={'First'} />
<Button title={'Second'} />
</React.Fragment>
)
})
},
});
Upvotes: -1