How to nested navigate between bottom tabs in React Navigation 6? - react-native

Given the structure:
Bottom tabs with lazy: false
TabOne
MainScreen
TabTwo
MainScreen
LevelTwoScreen
LevelThreeScreen
How I can navigate from TabOne -> MainScreen to get the route: TabTwo -> MainScreen -> LevelTwoScreen -> LevelThreeScreen?
Below code dont work, just navigates to TabTwoLevelTwoScreen:
navigation.navigate('TabTwoLevelTwoScreen', {
screen: 'TabTwoLevelThreeScreen',
})
I tried this structure too, not sucess:
Bottom tabs with lazy: false
TabOne
MainScreen
TabTwo
MainScreen
LevelTwoScreen
TabTwoNestedNavigator
LevelThreeScreen
This question started as a issue, see more here.
Thanks!

As said by #RajendranNadar, I'll go with the reset option:
navigation.reset({
routes: [
{
name: 'TabTwo',
state: {
routes: [
{ name: 'MainScreen' },
{ name: 'LevelTwoScreen' },
{ name: 'LevelThreeScreen' },
],
},
},
],
})

You will need to use the nested navigator as you have, but you need to start from the top and work down. Reference https://reactnavigation.org/docs/nesting-navigators#passing-params-to-a-screen-in-a-nested-navigator
navigation.navigate('TabTwo', {
screen: 'TabTwoNestedNavigator',
params: {
screen: 'LevelThreeScreen',
},
})
This answer is still relevant. I think you are confused about how the nested navigator works. In your snack you are navigating to pages that don't exist. Updating your code to the following makes it work.
<Button
title="Navigate to Tab Two - Level Three Screen"
onPress={() =>
navigation.navigate('TabTwo', {
screen: 'TabTwoNestedNavigator',
params: {
screen: 'TabTwoLevelThreeScreen'
},
})
}
/>
Snack: https://snack.expo.dev/#halecolin1/nested-navigation-between-bottom-tabs-does-not-works-in-react-navigation-6

Related

Back button handler working on every screen after changing drawer navigator in react - native

I am making a react native application in which there can be two type of user model and member.Now each having different drawer navigator as both having different data and both these drawer are inside a main stack navigator which is main navigator for the application. Now in both the both the drawer navigator .
const RootStack = createStackNavigator({
Splash : { screen: Splash },
PrivacyPolicy : { screen: PrivacyPolicy},
Welcome : { screen: Welcome },
Login : { screen: Login },
HomeMember: {screen: memberdrawerNavigator},
HomeModel: {screen: modeldrawerNavigator},
OtpChangePassword : { screen: OtpChangePassword},
}, {
headerMode: 'none',
initialRouteName: 'Splash'
})
I have a homepage different for both the member type and in both the home page i have implemented the back handler like this.
handleBackWithAlert = () => {
if (this.props.isFocused) {
if(this.state.loading_status){
this.setState({loading_status:false})
}
else{
Alert.alert(
'Exit App',
'Exiting the application?',
[
{
text: 'Cancel',
onPress: () => console.log('Cancel Pressed'),
style: 'cancel'
},
{
text: 'OK',
onPress: () => BackHandler.exitApp()
}
],
{
cancelable: false
}
);
}
return true;
}
}
componentWillMount() {
BackHandler.addEventListener('hardwareBackPress',this.handleBackWithAlert);
//this.props.navigation.dispatch(DrawerActions.closeDrawer());
this.props.navigation.closeDrawer();
}
componentWillUnmount() {
BackHandler.removeEventListener('hardwareBackPress', this.handleBackWithAlert);
}
Since i wanted to check back handling on only specific page so i exported my component like this.
export default withNavigationFocus(HomePage);
Now what the problem is that suppose i am using member account and after that i logout and then login with model account then this back handler is working on every screen why ? And if i close or kill that app without logout and restart then this problem disappears.
Here is my code called on logout
AsyncStorage.clear()
ToastAndroid.show("Logged Out Successfully !",ToastAndroid.SHORT);
const resetAction = StackActions.reset({
index: 0,
actions: [NavigationActions.navigate({ routeName: 'Welcome' })],
});
this.props.navigation.dispatch(resetAction);
Kindly help me to solve this problem. Thanks in advance.
According to my understanding, something is wrong with your BackHandler listeners. maybe you're not removing BackHandler listener on componentWillUnmount?

React navigation unable to navigate to just pervious screen after navigating multiple screens

Scenario:
Navigate: Screen 'StoreCategories' --> Screen 'QRScanner'
Back press while at Screen 'QRScanner' redirect to Screen 'StoreCategories' working perfectly
Navigate: Screen 'QRScanner' --> Screen 'Options' and
Navigate: Screen 'Options' --> Screen 'QRScanner' again
Click on back while at Screen 'QRScanner' redirect to Screen 'StoreCategories' again
Not redirecting to its previous Screen 'Options'.
Everything happens with default back functioning in react-navigation, I am not using any custom function for back functioning.
How can I resolve it and navigate to just previous from redirection happens rather than already cached screen in react-navigation(V2)?
const StackNavigator = defaultRoute =>
createStackNavigator(
{
CustomerLogin: {
screen: CustomerLogins
},
MerchantLogin: {
screen: MerchantLogin
},
Profile: {
screen: Profile
},
OtpVerification: {
screen: OtpVerification
},
StoreOffers: {
screen: StoreOffers
},
StoreCategories: {
screen: StoreCategories
},
QRScanner: {
screen: QRScanner
},
MerchantHome: {
screen: MerchantHome
},
CustomerHome: {
screen: CustomerHome
},
ThankYou: {
screen: ThankYou
},
Detail: {
screen: Detail
},
Options: {
screen: Options
},
PayOnline: {
screen: PayOnline
},
PayCash: {
screen: PayCash
},
PayTm: {
screen: PayTm
},
Token: {
screen: Token
},
AddDiscount: {
screen: AddDiscount
},
CustomerHistory: {
screen: CustomerHistory
},
Webview: {
screen: Webview
},
Direction: {
screen: Direction
}
},
{
initialRouteName: defaultRoute
}
);
The way the current React-Navigation's navigate function works is a bit different then how they work previously. Currently if you navigate to a screen that is already in the screen stack, the system would go back to that screen (removing the other screens between the current screen and that screen will be remove) instead of simply adding a new screen to the stack.
If you want to use the old system style, you can use push instead of navigate. This would simply add to the stack instead of going back to the last one (if exist in the stack).
So rather than use
const {navigate} = navigation;
navigate(nextScreen, params);
you use
const {push} = navigation;
push(nextScreen, params);
if You want to navigate to back screen, you can use this code:
this.props.navigation.goBack()
by navigate to Main it will redirect to initial route of Main and it seems to be A

React Native Navigation Drawer - Open page not in drawer

I am new to React Native development, so sorry if this seems obvious.
I have a new app that uses React Navigation Drawer as its main method of navigation. How can I have an onPress function within a page that navigates to a component that is not in my Navigation Drawer?
this.props.navigation.navigate('example') only seems to work for pages defined in the drawer.
My Drawer config:
const MyApp = createDrawerNavigator({
Interactive: {
screen: (props) => <Interactive {...props}
list={[
{ name: "First" },
{ name: "Second" },
{ name: "Third" },
{ name: "Fourth" },
{ name: "Fifth" },
{ name: "Sixth" },
{ name: "Seventh" },
{ name: "Eighth" },
]} />,
},
Settings: {
screen: SettingsScreen,
},
},
I am pressing a button within "Interactive" that should navigate to a component that is not include in the config above.
You can have multiple navigators inside your application (and usually this is the case), and actually every screen you want to navigate to should be defined inside a navigator. Every key in a navigator can be a single Screen or another navigator (Stack-, Drawer-, Tab- or SwitchNavigator).
const DrawerRoutes = createDrawerNavigator({
// your drawer navigator implementation ...
});
const MyApp = createSwitchNavigator(
{
Drawer: DrawerRoutes,
Example: YourScreen, // this would be the screen you want to navigator to
},
{
initialRouteName: 'Drawer'
}
);
And now you can navigate to YourScreen by simply calling this.props.navigation.navigate('Example') from within your Drawer.
In a react-navigation application it is not unusual to have a large combination of nested navigators, but there is always one root navigator.

Reset react-navigation Stack from Drawer

A lot of issues opened on official react-navigation github: https://github.com/react-community/react-navigation/issues but no one gives a real solution, including one post saying "look at this problem, a lot of issues": https://github.com/react-community/react-navigation/issues/691 without answer.
Basically: I have a DrawerNavigator with some nested StackNavigator.
export const MainNavigator = DrawerNavigator(
{
OrderNew: {
screen: OrderNew,
navigationOptions: {
drawerLabel: DrawerLabel('New Order')
}
},
Orders: {
screen: OrderNavigator, //a StackNavigator
navigationOptions: {
drawerLabel: DrawerLabel('Orders')
}
},
MenuNavigator: {
screen: MenuNavigator, //a StackNavigator
navigationOptions: {
drawerLabel: DrawerLabel('Menu')
}
},
//more screens...
{
initialRouteName: 'Orders',
drawerPosition: 'right',
contentComponent: props => <ScrollView style={{backgroundColor: 'rgba(227, 100, 29, .95)'}}><DrawerMenu state={props} /></ScrollView>,
}
);
So, I'm passing a contentComponent with my own menu component. My idea is to overwrite the onItemPress event of DrawerItems component and put my logic here.
What I want is: I would like to reset MenuNavigator (and other stack screens) every time users press that item. I just can't achieve this. As i said, I tried a lot of code. Actually, it's like this:
onItemPress={
router => {
const navigateAction = NavigationActions.navigate({
routeName: router.route.routeName,
});
this.props.state.navigation.dispatch(navigateAction);
}
}
The above code works, I can navigate through drawer items. Now, in my head, I just should pass an subaction resetting to the first item on navigator. So I tried:
onItemPress={
router => {
const navigateAction = NavigationActions.navigate({
routeName: router.route.routeName,
action: NavigationActions.reset({
index: 0,
actions: [
NavigationActions.navigate({routeName: router.route.routes[0].routeName}),
]
})
});
this.props.state.navigation.dispatch(navigateAction);
}
}
And explodes an error:
There is no route defined for key Menu.
Must be one of: 'Orders','OrderClient'
Summarizing: how could I reset StackNavigator when I do navigate to another DrawerNavigator's item?
You are missing key: null.
Navigation actions should be like this.
action: NavigationActions.reset({
index: 0,
key: null,
actions: [
NavigationActions.navigate({routeName: router.route.routes[0].routeName}),
]
})

RESET navigation - Drawer route with animation

Before all, I have to precise I searched arround as for example https://github.com/react-community/react-navigation/issues/1000 , https://github.com/react-community/react-navigation/issues/307 or even StackOverflow.
I have the following code :
/**** STACKNAVIGATOR 2 ****/
const HomeDrawer = StackNavigator({
HomeDrawerstack: { screen: Home, navigationOptions: { title: 'Accueil', } },
}, { initialRouteName: 'HomeDrawerstack', }
);
/**** STACKNAVIGATOR 3 ****/
const AddIdeaDrawer = StackNavigator({
AddIdeaDrawerRoot: { screen: AddIdea, navigationOptions: { title: 'AddIDea', } },
}, { initialRouteName: 'AddIdeaDrawerRoot', }
);
/**** DRAWERNAVIGATOR ****/
const DrawerRoutes = {
HomeRoot: {
screen: HomeDrawer,
navigationOptions: {
title: 'Home',
},
},
AddIdea: {
screen: AddIdeaDrawer
navigationOptions: {
title: 'Add an idea',
},
},
};
const DrawerOptions = {
initialRouteName: 'HomeRoot',
contentComponent: CustomDrawerContentComponent,
drawerWidth: 300,
};
export const Drawer = DrawerNavigator(DrawerRoutes, DrawerOptions);
/**** STACKNAVIGATOR 1 ****/
export const Navigation = StackNavigator({
HomeDrawerRoot: { screen: Drawer, navigationOptions: { header: null } },
OtherRoot: { screen: Contacts, navigationOptions: { /** **/ } },
}, { initialRouteName: 'HomeDrawerRoot', }
);
What I have tried
Currently, I'm trying to navigate from HomeDrawerstack to AddIdeaDrawerRoot with the StackNavigator animation and preventing the user to go back.
I have tried different solutions I have found on the different issues but any of them solve this problem.
First try :
navigate('AddIdea',)}
The app goes to AddIdea perfectly. However, the user can go back (that's normal I don't use RESET) and there is no animation. The AddIdea screen appears like that without any transition.
Second try :
NavigationActions.reset({
index: 0,
actions: [
NavigationActions.navigate({routeName: 'AddIdea',})
]
})
It doesn't work.
The logs prints : There is no route defined for key AddIdea. Must be one of: 'HomeDrawerstack'
Third try :
I read on an another issue https://github.com/react-community/react-navigation/issues/#1127 which explains that the key:null was the solution. So I tried the following action :
NavigationActions.reset({
index: 0,
key: null,
actions: [
NavigationActions.navigate({
routeName: 'HomeDrawerRoot',
action: NavigationActions.navigate({ routeName: 'AddIdea',}),
})
]
})
The app goes well to AddIdea. However, still with the possibility of going back to the last page (Home) and without animation.
Fourth try :
navigate({
routeName: 'HomeDrawerRoot',
action: NavigationActions.navigate({
routeName: 'AddIdea', action: NavigationActions.reset({
index: 0,
actions: [
NavigationActions.navigate({ routeName: AddIdeaDrawerRoot
]
})
})
})
It doesn't work. Printing : There is no route defined for key AddIdeaDrawerRoot. Must be one of: 'HomeDrawerstack'
What I'm trying to do
The only thing I want is going from HomeDrawerstack (Home screen) to AddIdeaDrawerRoot (AddIdea screen). With an animation like the StackNavigator animation and preventing the user of going back. (Disable Back action).
After reading a lot of issues, I didn't find any solutions. Is it a forget of the react-navigation ? Or I'm the problem ?! Thanks in advance.
My current configuration
| software | version
| ---------------- | -------
| react-navigation | ^1.0.0-beta.11
| react-native | 0.45.1
| node | 7.4.0
| npm or yarn | 0.24.5
I had similar problems and could not find a good example app. My navigation in my app crashed the app which was very frustrating. In the end I found a good working project to base my code on: https://github.com/paraswatts/DrawerNavigatorReactNative/
This project has working navigation with both tabs and drawers with no crashes and clean code. I hope it can help you.