React Native Navigation: Go to specific stack navigation screen - react-native

I'm using React Navigation 5.
At the top I have a Drawer navigator, with the following screens:
<Drawer.Navigator>
<Drawer.Screen name="One" component={StackNavigatorOne} />
<Drawer.Screen name="Two" component={StackNavigatorTwo} />
<Drawer.Screen name="Three" component={StackNavigatorThree} />
<Drawer.Navigator/>
Within StackNavigatorOne, I have a stack navigator,
<Stack.Navigator>
<Stack.Screen name="Screen1" component={Screen1} />
<Stack.Screen name="Screen2" component={Screen2} />
<Stack.Screen name="Screen2" component={Screen3} />
</Stack.Navigator>
In the StackNavigatorOne, the default order of screens is Screen1, Screen2, and Screen3, so that when this stack navigator is called, it shows Screen1 by default. I don't want to change this order.
However, from the Drawer Navigator, when a user clicks, DrawerScreen One, I want the user to go to Screen2 in StackNavigatorOne. Is it possible to do?

In React Navigation, you can check Nested Navigators.
Select your root component One first and then select the component inside the Stack Navigator.
navigation.navigate('One', {
screen: 'Screen2',
params: {
...
},
});
I assume, Clicking on back will go to your screen from where you navigated. If you want to go to Screen1, use lazy option as false. I've not tested this in drawerNavigator but for bottom navigator we used lazy option as false.

Related

React Navigation 6.x Initial Route Not Working

I'm using React Navigation 6.x's linking with Expo so that when a user clicks on a notification they are directed to the appropriate part of my application to interact with the new information. When my app is backgrounded (running in the background) and a user clicks on a notification they are redirected to the screen they need to be at, which works perfectly fine. However, when the app is killed and the user clicks on a notification, they are taken directly to the screen for which the url is provided and they cannot press back to navigate elsewhere in my application. I tried to resolve this by using the initialRouteName prop like is shown in the docs (link: https://reactnavigation.org/docs/configuring-links/#rendering-an-initial-route), but I cannot get it to work. For further clarification, when I mentioned above that I am able to get linking working it is in relation to the direct SettingsScreen, AddFriendScreen, and MessagingScreen links. What I cannot get working is the specific block of code inside the liking object that starts with HomeScreen. What I believe may be causing the issue is that I am trying to set my initialRoute as a screen within HomeScreen's Tabs.Navigator and then trying to route to a screen within my Stack.Navigator. However, the docs show that this is possible (link: https://reactnavigation.org/docs/configuring-links/#rendering-an-initial-route).
My code:
const linking = {
prefixes: [prefix],
config: {
screens: {
HomeScreen: {
initialRouteName: "Chats",
screens: {
AddFriendScreen: "addFriend",
CreateChatScreen: "createChatScreen",
Friends: "friends",
MessagingScreen: 'messagingScreen/:chatRoomId'
}
},
SettingsScreen: "SettingsScreen",
AddFriendScreen: "AddFriendScreen",
MessagingScreen: 'MessagingScreen/:chatRoomId'
},
}
};
<NavigationContainer linking={linking} theme={MyTheme} >
<Stack.Navigator>
{!authState.value ?
<>
<Stack.Screen name="LoginScreen" component={LoginScreen} />
<Stack.Screen name="SignUpScreen" component={SignUpScreen} />
<Stack.Screen name="ForgotPasswordScreen" component={ForgotPasswordScreen} />
</>
:
<>
<Stack.Screen name="HomeScreen" component={HomeScreen} />
<Stack.Screen name="MessagingScreen" component={MessagingScreen} />
<Stack.Screen name="SettingsScreen" component={SettingsScreen} />
<Stack.Screen name="CreateChatScreen" component={CreateChatScreen} />
<Stack.Screen name="AddFriendScreen" component={AddFriendScreen} />
</>
}
</Stack.Navigator>
</NavigationContainer>
const HomeScreen = () => {
return (
<Tabs.Navigator>
<Tabs.Screen name="Chats" component={ChatScreen} />
<Tabs.Screen name="Friends" component={FriendsScreen} />
<Tabs.Screen name="Profile" component={ProfileScreen} />
</Tabs.Navigator>
)
}
Hmm, I would put any screen that I would like to access in multiple navigators at the root level so that they can both reach it.
For my own project, I have a root stack with a dedicated auth stack and an app/home stack (which is a tab nav like your HomeScreen). And outside that I have all my modal and root screens that I'd like other navigators to access (Because I really have two Home tab navigators the user can switch between.)
Idk if putting all of your screens listed after HomeScreen outside of that object will help your situation, but you can try that.

React Navigation Tab Screens don't show up as separate screens in history

I have a Tab Navigator with 3 screens: Home, Camera, and Profile. I then have a stack navigator which references the tab navigator, and have a screen in this stack navigator called Camera2.
const Navigation = () => {
return (
<NavigationContainer>
<Stack.Navigator>
<Stack.Screen name="Home" component={TabNavigator} />
<Stack.Screen name="Camera2" component={Camera2Screen} />
</Stack.Navigator>
</NavigationContainer>
);
};
const TabNavigator = () => {
return (
<Tab.Navigator backBehavior="history" initialRouteName="Home">
<Tab.Screen name="Home" component={HomeScreen} />
<Tab.Screen name="ToCamera" component={ToCameraScreen} />
<Tab.Screen name="Profile" component={ProfileScreen} />
</Tab.Navigator>
);
};
Suppose I start at the Home screen, then navigate to the Camera screen by selecting the camera tab. Then in the Camera screen I use navigation.replace("Camera2"). At this point, in the Camera2 screen I would want the navigation history to look like [Home, Camera2] since the Camera screen had been removed from history. However, what I end up seeing is [Camera2].
After doing some research I realized this was happening since the tab navigator acts as a single screen in the stack navigator, so seperate tabs show up as a single screen in navigation history. So if I remove the Camera screen from history it essentially removes all Tab Navigator screens (including the Home screen).
I realize this is the expected behaviour but I was wondering how I can get the desired behaviour.

What is the difference between nesting a Drawer navigator inside a Stack navigator, or the opposite?

In the documentation for version 6.x of React Navigation, in fundamentals, Navigating to a screen in a nested navigator, they have an example of nesting a Drawer navigator inside of a Stack navigator.
function Root() {
return (
<Drawer.Navigator>
<Drawer.Screen name="Home" component={Home} />
<Drawer.Screen name="Profile" component={Profile} />
<Stack.Screen name="Settings" component={Settings} />
</Drawer.Navigator>
);
}
function App() {
return (
<NavigationContainer>
<Stack.Navigator>
<Stack.Screen
name="Root"
component={Root}
options={{ headerShown: false }}
/>
<Stack.Screen name="Feed" component={Settings} />
</Stack.Navigator>
</NavigationContainer>
);
}
Why is it shown like this and not the Drawer as the parent navigator and the Stack inside?
I've seen other examples that do this (Drawer parent, Stack inside) but I don't understand what the difference in terms of layouts or the final UI.
Asked somewhere else and got this answer:
If stack is nested inside drawer - you can still open drawer in any
stack screen, etc
if drawer is nested inside stack - drawer will be
only present in the screen that drawer is, and cannot be seen as other
screens will render above it

React-native going back from a nested navigation container does not work

I am creating a nested navigation container in react-native and the stack looks like this:
-Main Navigation Container:
- Home
- Market Navigation Container:
- Market
- Cart
- About
When I go to home or about and go back, it works properly. However, when I go back from Market or cart (Which I expect to go to the Home page) it shows an error saying:
The action 'POP' with payload {"count":1} was not handled by any navigator.
Is there any screen to go back to?
This is a development-only warning and won't be shown in production.
This is my code for the main navigation container:
<NavigationContainer independent={true}>
<Stack.Navigator>
<Stack.Screen options={myOptions} name="Home" component={Home} />
<Stack.Screen
options={{ headerShown: false }}
name="MarketNavigation"
component={MarketNavigation}
/>
<Stack.Screen options={myOptions} name="About" component={About} />
</Stack.Navigator>
</NavigationContainer>
And this is my code for the market navigation:
<NavigationContainer ref={navigationRef} independent={true}>
<Stack.Navigator>
<Stack.Screen
options={myOptions}
name="Market"
component={Market}
/>
<Stack.Screen
options={myOptions}
name="Cart"
component={Cart}
/>
</Stack.Navigator>
</NavigationContainer>
I faced this when navigating to nested navigator using "screen" option like this:
navigation.navigate('Root', {
screen: 'Settings'
})
;
As mentioned in the documentation:
By default, when you navigate a screen in the nested navigator, the
specified screen is used as the initial screen and the initial route
prop on the navigator is ignored.
To solve this you should use "initial: false" like so:
navigation.navigate('Root', {
screen: 'Settings',
initial: false,
});
Could you add in the code where you navigate from Home to MarketNavigation and back?

React Navigation Reset on Nested Navigator

I am using React-Navigation v 5.0.1, I have a Drawer navigator nested inside Stack navigator that looks like this:
MainStack.js
function MainStack() {
return(
<Stack.Navigator>
<Stack.Screen name="Splash" component={Splash} />
<Stack.Screen name="Login" component={Login} />
<Stack.Screen name="HomeDrawerStack" component={HomeDrawerStack} />
</Stack.Navigator>
)
}
HomeDrawerStack.js
function HomeDrawerStack() {
return (
<Drawer.Navigator>
<Drawer.Screen name="Home" component={Home} />
</Drawer.Navigator>
)
}
When I tap a logout button on Home screen, how do I navigate to Login screen and reset / clear all other screens? (so it triggers the componentWillUnmount on other screens)
This code will navigate to Login Screen after clearing the stack. so that back button or back swipe will not work to navigate to HomeDrawerStack
navigation.reset({
index: 0,
routes: [{ name: "Login" }],
});
if I share how I handled it, it is like, I am sharing my code snippet as png here, so what I have done is appended Navigator with redux, and I use to change my stack or replace my stack by dispatching event to store attached to Navigator.