Unable to Navigate to a StackNavigator nested in a DrawerNavigator - react-native

I started with a drawer navigation to allow me to pick a category page as a starting point. From each category page I want to create a stack navigator so that it navigates with a stack without each page displayed in the drawer. I started by adding a StackNavigator to the "product" page, but was told to move it to the app page and used a nest navigator. So far, this is what I have...
App.js ( Nested Navigators )
export default function App() {
return (
<NavigationContainer>
<Drawer.Navigator
initialRouteName="LoL"
drawerStyle={{
backgroundColor: "#212121",
}}
drawerContentOptions={{
activeTintColor: "orange",
inactiveTintColor: "white",
}}
>
<Drawer.Screen name="LoL" component={LoL} />
<Drawer.Screen name="CSGO" component={CSGO} />
<Drawer.Screen name="matchDetailsnav" component={matchDetailsNav} />
</Drawer.Navigator>
</NavigationContainer>
);
}
const matchDetailsNav = () => {
<Stack.Navigator>
<Stack.Screen name="MatchDetails" component={MatchDetails} />
</Stack.Navigator>
}
If we navigate to LoL.js we will see a list of cards to click on. I am using the following code to generate routes for each card.
{matches.map((match, index) => {
return (
<View>
<TouchableOpacity
key={index}
onPress={() => navigation.navigate('matchDetailsNav', match)}
>
<Card
.. passing some props here..></Card>
</TouchableOpacity>
</View>
This is where I started to get the following error...
The action 'NAVIGATE' with payload {** .. obj of the props im passing .. not important to question *} was not handled by any navigator.
Do you have a screen named 'MatchDetails?
If you're trying to navigate to a screen in a nested navigator, see https://reactnavigation.org/docs/nesting-navigators#navigating-to-a-screen-in-a-nested-navigator.
This was happening before I added the stack navigator but I am not sure why. I am importing the MatchDetails page into the App.js, there is not naming typo in my code, and I cannot seem to find why it doesn't see my match details page. Why is it not picking up my page?
EDIT: I just noticed that adding the nested navigator like I did in the example above put the name "matchDetailsNav" in my drawer nav as a clickable link, which is not what I want.
I simply want to gave a drawer nav and then have regular stack navigation for the pages/screens that link within the drawer nav. This way, clicking on a card living on a screen that is accesable from the Drawer Nav should use a stack nav ( allowing for the back button and sliding animation ).
I hope this edit clears up exactly what I am trying to do.

Related

How can I redirect from StackNavigator screen to BottomTabNavigator screen

I'm working on an app in React-Native. How I'm trying to achieve this is by using a SignUpCompleted Flag and checking if its true/false to decide if the page should navigate to the next signup screen or just to the homepage. I have 3 screens as part of the sign-up process that I only want to be shown the 1st time the app opens. I have the 3 screens in a StackNavigator and I'm trying to navigate from the last StackNavigator screen to a BottomTabNavigator screen. Sadly I get the following error:
The action 'NAVIGATE' with payload {"name":"HomeStack"} was not handled by any navigator.
My current setup is as follows:
SignUpStack
const SignUpStack = createStackNavigator();
export default function SignUpStackScreen() {
const [signUpCompleted, setSignUpCompleted] = useState(false);
return (
<SignUpStack.Navigator initialRouteName="Welcome" screenOptions={{ headerShown: false }}>
<SignUpStack.Screen name="Welcome" component={WelcomeScreen} initialParams={{signUpCompleted}} />
<SignUpStack.Screen name="Department" component={ChooseDepartment} initialParams={{signUpCompleted}} />
<SignUpStack.Screen name="InputName" component={InputName} initialParams={{signUpCompleted, setSignUpCompleted}}/>
</SignUpStack.Navigator>
);
}
From the InputName component I try to redirect to a BottomTabNavigator Screen called homename
The redirect code is as follows: - in InputName component
<TouchableOpacity
style={[styles.shadow]}
onPress={() => {navigation.navigate("HomeName"); setSignUpCompleted(true)}}
>
The BottomTabNavigator is as follows: - I'm trying to redirect to HomeStack component
-const Tab = createBottomTabNavigator();
export default function Tabs() {
return (
<Tab.Navigator initialRouteName={homeName} >
<Tab.Screen name={ResultsName} component={ResultatenStack} />
<Tab.Screen name={homeName} component={HomeStack} />
<Tab.Screen name={settingsName} component={SignUpStack} />
</Tab.Navigator>
);
}
When using the same navigation method to direct to screens that are in the stack that I already am, it works fine. I hope someone can give me any pointers or help out! If you need any more info feel free to reach out!
PS: I'm very new to react-native so my apologies if I'm missing information.
I geas you are trying to navigate from stack navigator to tab navigator which is not ideal in react native you have to use nesting navigator
what I mean you have to use the tab navigator as a screen inside the stack navigator
this is React Navigation doc for nesting navigator https://reactnavigation.org/docs/nesting-navigators/

React Native drawer navigator to stack navigator missing transition animation

I have a functional Drawer navigator that holds a Stack navigator as shown below:
function DrawerNavigator() {
return (
<Drawer.Navigator>
<Drawer.Screen
name="Categories"
component={CategoriesScreen}
... />
),
}}
/>
<Drawer.Screen
...
</Drawer.Navigator>
);
}
...
return (
<>
...
<NavigationContainer onReady={onLayoutRootView}>
...
<Stack.Screen
name="MealCategories"
component={DrawerNavigator}
options={{ headerShown: false }}
/>
While in the 'Favorites' screen, which is registered under the Drawer Navigator, when attempting to navigate to 'Categories' page which is registered under Stack navigator (but pointed to using Drawer navigator) using navigation.navigate(), there's no navigation animation.
const buttonPressHandler = () => {
navigation.navigate("Categories");
};
Yup it seems the drawer navigator has no support for screen animation. So it all looks great when using the drawer to navigate. But if navigating through links in the page or actions, theres no navigation animation between screens. Been hunting for hours now and I think its simply not implemented.

Create Bottom Tab Navigator Using CMS Content

I have a React Native application where the tabs in the bottom tab navigator will be authored through Drupal. As a result I need to not hard-code the various tabs in the navigator. I tried the following:
screenOptions={{
tabBarStyle: { display: isAuthenticated ? undefined : 'none' },
}}
>
{mockData.map({ item => {
<Tab.Screen
name={item.name}
component={item.route}
/>
}})}
</Tab.Navigator>
but I keep getting an error that there are no screens for the navigator, so it seems putting it inside a map is making it invisible. I'm getting frustrated with how to get this content into the navigator.

How do I add a navigation button to a React Navigation Stack header with nested Bottom Tab Navigator?

I am trying to build a mobile app in react-native and I'm having some problems setting up React Navigation.
What I want to achieve is a Bottom Tab Navigator that Navigates to the 'Home' screen and the 'Profile' Screen. From the 'Home' screen, there should be a button to navigate to the 'Settings' screen in the Header.
I have got to the point where I have a Bottom Tab Navigator that can successfully navigate between the 'Home' and 'Profile' screens, as well as a button on the header for the Settings screen using the Stack navigation header. However, I am having trouble navigating to the 'Settings' screen with this button.
My code for the Stack navigator is:
const MainStackNavigator = () => {
return (
<Stack.Navigator screenOptions={screenOptionStyle}>
<Stack.Screen
name="Home"
component={HomeScreen}
options = { ({navigation}) => ({
title: "Home",
headerStyle: {
backgroundColor: '#ff6600',
},
headerRight: () => (
<Button
onPress={() => navigation.navigate(SettingScreen)}
title="Settings"
color="#fff"
/>
)
})}
/>
<Stack.Screen name="Settings" component={SettingScreen} />
</Stack.Navigator>
);
}
When I click on the Settings button, I get the error:
"The action 'NAVIGATE' with payload undefined was not handled by any navigator.
Do you have a screen named 'SettingScreen'?"
Upon looking for a solution to this error I found this article: Nesting Navigators
It recommends keeping nested navigators to a minimal. Is my method even the right way about going for this UI design? Is there a way to achieve this with only using one navigator?
After some time trying to solve this I found the problem was quite silly of me. navigation.navigate takes the name of the screen to navigate to, but I was giving it the component.
To fix the problem I changed
onPress={() => navigation.navigate(SettingScreen)}
to
onPress={() => navigation.navigate('Settings')}
Add this below your render method!
render () {
const { navigate } = this.props.navigation;
}
And then in the onPress
onPress={() => navigate(SettingScreen)}
Hopefully this helps

Navigate from a screen in one navigator to a screen in another navigator

I am using react-navigation v5.
In my app. I have two navigators, one stack navigator one drawer navigator:
const LoginStack = createStackNavigator();
const Drawer = createDrawerNavigator();
I show either one based on login status:
{state.loggedIn? (
<LoginStack.Navigator
...>
<LoginStack.Screen
name='login'
component={LoginScreen}
/>
<LoginStack.Screen
name='register'
component={RegisterScreen}
/>
</LoginStack.Navigator>
) : (
<>
<Drawer.Navigator
initialRouteName={Landing}
drawerContent={props => <MyDrawerContent {...props} />}
>
<Drawer.Screen name="landing" component={LandingScreen} />
...
</Drawer.Navigator>
</>
)}
As you can see above, if user is not logged in I show LoginStack navigator , otherwise I show Drawer navigator. And if you look closely in the Drawer.Navigator part, I have declared my own drawer content MyDrawerContent.
Inside MyDrawerContent, I have a logout button. I would like to navigate user to the LoginScreen of LoginStack. I tried :
<Button title="Logout" onPress={() => props.navigation.navigate('login')}/>
But I get error: The action 'NAVIGATE' with payload {"name":"Login"} was not handled by any navigator.. Is it because I am navigating to a screen of another navigator which MyDrawerContent doesn't belong to? How to resolve it?
Since you create two completely separate navigation trees, you cannot navigate between them because login screen is not registered, and thus not available, when you're in the Drawer.Navigator.
However, what you really want to do instead in your Logout button onPress, is change the loggedIn state to false. That will re-render the main app component and render the LoginStack instead. It's not very clear how you pass the state down the component tree so I can't provide a specific code example but hopefully you get the idea.