React Navigation 6.x Initial Route Not Working - react-native

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.

Related

React Native Login to Home Screen navigation

I'm new to React Native, and want to build a login page that connects to the home page, but if I use a single stack navigator, I get the little arrow in the top lefthand corner that just allows the user to go back to the login page without clicking on the logout button, which wouldn't log them out correctly. How can I make it so that arrow goes away on the Home Screen? Do I need to make 2 stack navigators and link them together somehow? I don't have any code written yet, I'm just looking for a general explanation before I get started.
Got it, need to set "headerLeft" to null in the Stack Screen
You can also check the documentation of React Navigation authentication flow
according to the documentation Don't manually navigate when conditionally rendering screens between Auth and Home screens.
isSignedIn ? (
<>
<Stack.Screen name="Home" component={HomeScreen} />
<Stack.Screen name="Profile" component={ProfileScreen} />
<Stack.Screen name="Settings" component={SettingsScreen} />
</>
) : (
<>
<Stack.Screen name="SignIn" component={SignInScreen} />
<Stack.Screen name="SignUp" component={SignUpScreen} />
</>
);
Full documentation of React Navigation

How to make a stack navigator cover entire screen using React Navigation

I am building a React Native project with Expo. For navigation, I am using react-navigation 6.0 with the following code for my main component:
export default class App extends Component {
render() {
return (
<NavigationContainer>
<Stack.Navigator initialRouteName={'SignIn'} screenOptions={{
headerShown: false
}}>
<Stack.Screen name="SignIn" component={SigninScr} />
<Stack.Screen name="SignUp" component={SignupScr} />
<Stack.Screen name="EmailVerification" component={EmailVerificationScr} />
</Stack.Navigator>
</NavigationContainer>
);
}
}
This works fine, but I haven't been able to make Stack.Navigator cover the entire screen. There is a weird area that's not covered by the Stack.Navigator:
I was reading through some of the documentation about stack navigator, but couldn't find any props or styling to force it to cover 100% of the screen. Does anyone know how to accomplish this?

How can I pass parameters to another tab navigation screen

Hi guys I'm still new to react native, I wanted to ask how can I pass a parameter to another screen? I'm currently doing a login system which going to access the email of the user and show their email on their profile page after they logged in. I've tried { this.props.navigation.state.params.Email } in the profile.js but it shows an error says that
TypeError: undefined is not an object (evaluating 'this.props.navigation.state.params')
I saw some related solutions as well but those were for stack navigator but I'm using bottom tab navigation so I wasn't sure if they work in the same way.
login.js
this.props.navigation.navigate('Profile', { Email: email });
app.js
export default function App() {
return (
<NavigationContainer>
<Tab.Navigator>
<Tab.Screen name="Home" component={getTransaction} />
<Tab.Screen name="addTransaction" component={addTransaction} />
<Tab.Screen name="Register" component={register} />
<Tab.Screen name="Login" component={login} />
<Tab.Screen name="Profile" component={profile} />
</Tab.Navigator>
</NavigationContainer>
);
}
in your Profile screen page:
export const profile = ({route}) => {
const { Email } = route.params;
}
Then you can use 'Email' as a regular constant.
https://reactnavigation.org/docs/params/
I believe you should get the params from props.router instead of props.navigation.

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.