React-Navigation: Cannot hide header with nested navigators - javascript

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
}

Related

react-native-navigation: How to go to a special page without tab bar?

I'm new to React Native.
I want to create two pages:
'Login': without tab bar
'Layouts': with tab bar.
I tried to show the 'Login' page at start, but it always go to 'Layouts' page.
How to show 'Login' page first?
import { persistStore } from 'redux-persist';
import { Navigation } from 'react-native-navigation';
...
class App extends React.Component {
...
startApp = () => {
Navigation.startTabBasedApp({
screen: {
screen: 'Login',
navigatorStyle: {
...
},
},
tabs: [
{
screen: 'Layouts',
icon: iconsMap.home,
selectedIcon: selectIconsMap.home,
},
...
When you are difining your tabs there in navigationOptions you can pass visible: false for hiding tabbar on particular screen.
Check out this comment from github issue for more information.
Maybe this will help you: https://github.com/react-navigation/react-navigation/issues/581#issuecomment-284248914

React Navigation SwitchNavigator - navigate between several stacks

I had to refactor recently the navigation inside my React Native App using React Navigation.
Indeed, I have several navigators inside my app for different purposes: screens when not connected, screens when connected and some screens that should be available in both situations
(e.g. terms of use).
So my question is the following, if I have this pattern, how can I for example navigate from TermsOfUse to Register without going back to Welcome?
I can't use navigate.goBack() or navigation.navigate('Register') since those screens are not in the same StackNavigator, and duplicate the TermsOfUse in both navigators would be quite dirty.
// Screens
const NotConnectedScreens = {
Welcome: { screen: WelcomeScreen },
Register: { screen: RegisterScreen },
}
const ConnectedScreens = {
Homepage: { screen: HomepageScreen },
Tutorial: { screen: TutorialScreen },
}
const OthersScreens = {
TermsOfUse: { screen: TermsOfUseScreen },
}
// Stacks
const NotConnectedStack = createStackNavigator(NotConnectedScreens, {
initialRouteName: 'Welcome',
})
const ConnectedScreens = createStackNavigator(ConnectedScreens, {
initialRouteName: 'Homepage',
})
const OtherStack = createStackNavigator(OtherScreens, {
initialRouteName: 'TermsOfUse',
})
// App navigation
const AppContainer = createAppContainer(
createSwitchNavigator(
{
NotConnectedStack: NotConnectedStack,
ConnectedStack: ConnectedStack,
OthersStack: OthersStack,
},
{
initialRouteName: 'LandingStack',
defaultNavigationOptions: {
header: null,
headerMode: 'none',
},
}
)
)
export { AppContainer as default }
I can't use navigate.goBack() or navigation.navigate('Register') since
those screens are not in the same StackNavigator.
Not completely true, if your screen has a unique name, wherever you need to navigate to that page you can call the function this.props.navigation.navigate('SecondPage').
but sometimes going to an screen from another stack can't be done because it needs some data to be passed when navigating to. in this case MAKE SURE YOUR SCREEN HAS A DIFFERENT NAME
DevicesList: {screen: DevicesList },// this is wrong
DevicesListPage: {screen: DevicesList },// this is right
then you can navigate to that page like below from another stack:
this.props.navigation.navigate('DevicesListPage', {
//your data
});

React Navigation: Component is not being unmounted on pop or back button #5775

I am having an issue when I navigate from Home component that contains a list of companies and I press in a button to load the Company view, the data is being loaded but when I press back in Android is returning to Home and when I press in a different company button to load its details, is rendering the same view with the same previous data, that means, the component is not being updated/unmounted.
These are my routes
const drawerConfig = {
initialRouteName: 'Home',
contentComponent: SideMenu,
drawerWidth: width,
}
const MainDrawerNavigator = createDrawerNavigator(
{
Home: {
screen: Home,
},
Company: {
screen: Company,
},
Gifts: {
screen: Gifts,
},
Contact: {
screen: Contact
}
},
drawerConfig,
);
const InitialStack = createStackNavigator(
{
Menu: {
screen: Menu,
path: 'menu/',
}
},
{
initialRouteName: 'Menu',
headerMode: 'none',
}
);
const SwitchNavigator = createSwitchNavigator(
{
Init: InitialStack,
App: MainDrawerNavigator,
},
{
initialRouteName: 'Init',
}
);
const AppContainer = createAppContainer(SwitchNavigator);
export default AppContainer;
I am navigating from Home to Company with this
goToCompany = company => event => {
this.props.navigation.navigate('Company', {
company,
});
}
And receiving the params in Company with this
componentWillMount() {
this.setState({ companyData: this.props.navigation.getParam('company', {}) });
}
So I am expecting the Company component will unmount on pop or allow me to change the state of the Company component when I send the details from Home.
I am using react-navigation 3.5.1 and react-native 0.59.3
React native navigation does not work as web. Read here for more details. https://reactnavigation.org/docs/en/navigation-lifecycle.html
When you navigat to other screen it doesn't actually get unmounted. Read documentation for details.
Use willFocus instead.
you can try using componentDidUpdate check in docs
componentDidUpdate(prevProps) {
// Typical usage (don't forget to compare props):
if (this.props.userID !== prevProps.userID) {
this.fetchData(this.props.userID);
}
}
You need to use the push method of navigation object. The push replace the current route with a new and the navigate search a route and if not exist create new one.

How not to unmount previously opened screen of Drawer Navigator

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.

How to navigate from a child Stack Navigator back to parent while resetting navigation stack at the same time, in React Native

I've read countless react-navigation docs, and I know there is way to do this, but it's definitely what I would call non-trivial and definitely non-intuitive.
I have a root navigation stack:
export const NavigationStack = StackNavigator({
Splash: {
screen: Splash
},
Signup: {
screen: Signup
},
Login: {
screen: SignIn
},
ForgottenPassword: {
screen: ForgottenPassword
},
Discover: {
screen: Discover
},
ProfileShow: {
screen: ProfileShow
}
}, {
headerMode: 'none'
})
The ForgottenPassword screen is a child Stack Navigator:
import { StackNavigator } from 'react-navigation'
import PasswordResetProcess from './index'
const ForgottenPassword = StackNavigator({
ResetPassword: {
screen: PasswordResetProcess
}
}, {
headerMode: 'none'
})
export default ForgottenPassword
On that index.js Container Component, there is a sub-component that I pass navigation to, like this:
switch (lastCompletedStep) {
case NEW_RESET_REQUEST:
return <InputTel navigation={navigation} />
case INPUT_TEL:
return <ResetPassword navigation={navigation} />
That ResetPassword component is the one in question. It triggers an action creator and passes this.props.navigation into the action creator:
await props.handleResetSubmit(token, props.navigation)
From inside this action creator, props.navigation is available as navigation. I can do this fine:
navigation.navigate('Discover') // see how this is from the root Navigation Stack
I cannot, however, do this:
navigation.dispatch({
type: 'Navigation/RESET',
index: 0,
actions: [{ type: 'Navigate', routeName: 'Discover' }]
})
It throws this error:
[edit] I just tried this and it also generated the same error:
navigation.dispatch(NavigationActions.reset({
index: 0,
actions: [NavigationActions.navigate({ routeName: 'Discover' })]
}))
How do I reset the stack while navigating to Discover from here?
I feel like the answer is to navigate to discover and reset the stack at the same time as some kind of child operation, but I don't know where to begin putting that together. The react-navigation documentation is horrendous for illustrating child to parent operations.
Here is my best guess at what it approximately has to look like:
navigation.dispatch({
type: 'Navigation/NAVIGATE',
routeName: 'Discover',
actions: [{ type: 'Reset', index: 0, key: null }]
})
I just solved it with this code:
navigation.dispatch(NavigationActions.reset({
index: 0,
key: null,
actions: [NavigationActions.navigate({ routeName: 'Discover' })]
}))
The secret was to add key: null, which I have seen people doing before. It is a very important element for times when you are resetting.
Here is the documentation I found that illustrates it:
https://github.com/react-community/react-navigation/issues/1127
I think this works because NavigationActions has knowledge of the root navigation stack, so it works for the same reason navigation.navigate('Discover') worked (in the context of my code in this question).
in version >2 of react navigation, NavigationActions.reset() doesnt work.
You should use StackActions.reset() instead:
import { NavigationActions, StackActions } from 'react-navigation';
const resetStackAction = StackActions.reset({
index: 0,
actions: [NavigationActions.navigate({ routeName: 'Discover' })],
});
this.props.navigation.dispatch(resetStackAction);

Categories

Resources