admin管理员组文章数量:1391925
I'm building a react native app and using react navigation v6 library. I've built a react navigator that works fine for the most part, but I'm facing this bug when navigating to a certain page.
I have a stack navigator:
<NavigationContainer>
<Stack.Navigator >
<Stack.Screen name='LandingScreen' ponent={LandingScreen} options={{headerShown: false}} />
<Stack.Screen name='LoginScreen' ponent={LoginScreen} options={{headerShown: false}} />
<Stack.Screen name='RegisterScreen' ponent={RegisterScreen} options={{headerShown: false}} />
<Stack.Screen name='CocktailDetailScreen' ponent={CocktailDetailScreen} options={{ header: () => <Header/> }} />
<Stack.Screen name='HomeScreen' ponent={DrawerNavigator} options={{ header: () => <Header/> }} />
</Stack.Navigator>
</NavigationContainer>
And the drawer navigator:
<Drawer.Navigator screenOptions={{
drawerStyle: {
backgroundColor: 'white',
zIndex: 100
},
drawerPosition: 'right'
}}>
<Drawer.Screen name='Search cocktails' ponent={HomeScreen} options={{headerShown: false}} />
<Drawer.Screen name='Profile' ponent={ProfileScreen} options={{headerShown: false}} />
<Drawer.Screen name='Publish a recipe' ponent={PublishRecipeScreen} options={{headerShown: false}} />
<Drawer.Screen name='Favorites' ponent={FavoritesScreen} options={{headerShown: false}} />
<Drawer.Screen name='Published recipes' ponent={PublishedRecipesScreen} options={{headerShown: false}} />
<Drawer.Screen name='Log out' ponent={LandingScreen} options={{headerShown: false}} />
</Drawer.Navigator>
The problem occurs when navigating to CocktailDetailScreen, the thing is the drawer just won't open. The drawer is opened from the header ponent (which is shared by CocktailDetailScreen, homeScreen and all the screens within the drawer) and to open it I'm using navigation.dispatch(DrawerActions.toggleDrawer())
. This works fine on every screen except of this one.
I've figured that If I remove CocktailDetailScreen from the stack navigator and add it to the drawer navigator, then the drawer opens normally. But I don't want this, since this page should only be accessed through other screens, not directly from the "menu"/navigator.
I'm sure this is possible, but I don't get what I'm doing wrong. Maybe I'm not nesting the navigators correctly or the screen shouldn't be in the navigator at all?
Full code is here:
I'm building a react native app and using react navigation v6 library. I've built a react navigator that works fine for the most part, but I'm facing this bug when navigating to a certain page.
I have a stack navigator:
<NavigationContainer>
<Stack.Navigator >
<Stack.Screen name='LandingScreen' ponent={LandingScreen} options={{headerShown: false}} />
<Stack.Screen name='LoginScreen' ponent={LoginScreen} options={{headerShown: false}} />
<Stack.Screen name='RegisterScreen' ponent={RegisterScreen} options={{headerShown: false}} />
<Stack.Screen name='CocktailDetailScreen' ponent={CocktailDetailScreen} options={{ header: () => <Header/> }} />
<Stack.Screen name='HomeScreen' ponent={DrawerNavigator} options={{ header: () => <Header/> }} />
</Stack.Navigator>
</NavigationContainer>
And the drawer navigator:
<Drawer.Navigator screenOptions={{
drawerStyle: {
backgroundColor: 'white',
zIndex: 100
},
drawerPosition: 'right'
}}>
<Drawer.Screen name='Search cocktails' ponent={HomeScreen} options={{headerShown: false}} />
<Drawer.Screen name='Profile' ponent={ProfileScreen} options={{headerShown: false}} />
<Drawer.Screen name='Publish a recipe' ponent={PublishRecipeScreen} options={{headerShown: false}} />
<Drawer.Screen name='Favorites' ponent={FavoritesScreen} options={{headerShown: false}} />
<Drawer.Screen name='Published recipes' ponent={PublishedRecipesScreen} options={{headerShown: false}} />
<Drawer.Screen name='Log out' ponent={LandingScreen} options={{headerShown: false}} />
</Drawer.Navigator>
The problem occurs when navigating to CocktailDetailScreen, the thing is the drawer just won't open. The drawer is opened from the header ponent (which is shared by CocktailDetailScreen, homeScreen and all the screens within the drawer) and to open it I'm using navigation.dispatch(DrawerActions.toggleDrawer())
. This works fine on every screen except of this one.
I've figured that If I remove CocktailDetailScreen from the stack navigator and add it to the drawer navigator, then the drawer opens normally. But I don't want this, since this page should only be accessed through other screens, not directly from the "menu"/navigator.
I'm sure this is possible, but I don't get what I'm doing wrong. Maybe I'm not nesting the navigators correctly or the screen shouldn't be in the navigator at all?
Full code is here: https://github./coccagerman/mixr
Share Improve this question asked Feb 3, 2022 at 1:38 German CoccaGerman Cocca 8492 gold badges14 silver badges21 bronze badges2 Answers
Reset to default 4Drawer Navigator is nested inside Stack Navigator, Screens below can access drawer specific actions ( open, close or toggle)
- Search cocktails
- Profile
- Publish a recipe
- Favorites
- Published recipes
- Log out
due to they are children to a Drawer navigator.
To make Drawer actions accessible to all screens, the Drawer must be a parent to all navigators.
Let's refactor our code as below.
const PublicStack = (
<Stack.Navigator>
<Stack.Screen
name="LandingScreen"
ponent={LandingScreen}
options={{ headerShown: false }}
/>
<Stack.Screen
name="LoginScreen"
ponent={LoginScreen}
options={{ headerShown: false }}
/>
<Stack.Screen
name="RegisterScreen"
ponent={RegisterScreen}
options={{ headerShown: false }}
/>
<Stack.Screen
name="CocktailDetailScreen"
ponent={CocktailDetailScreen}
options={{ header: () => <Header /> }}
/>
<Stack.Screen
name="HomeScreen"
ponent={DrawerNavigator}
options={{ header: () => <Header /> }}
/>
</Stack.Navigator>
);
const ProtectedStack = () => (
<Stack.Navigator>
<Stack.Screen
name="Search cocktails"
ponent={HomeScreen}
options={{ headerShown: false }}
/>
<Stack.Screen
name="Profile"
ponent={ProfileScreen}
options={{ headerShown: false }}
/>
<Stack.Screen
name="Publish a recipe"
ponent={PublishRecipeScreen}
options={{ headerShown: false }}
/>
<Stack.Screen
name="Favorites"
ponent={FavoritesScreen}
options={{ headerShown: false }}
/>
<Stack.Screen
name="Published recipes"
ponent={PublishedRecipesScreen}
options={{ headerShown: false }}
/>
<Stack.Screen
name="Log out"
ponent={LandingScreen}
options={{ headerShown: false }}
/>
</Stack.Navigator>
);
const MainStack = () => {
// Mocked logic for authentication, Implement actually logic
const isLoggedIn = true;
return (
<NavigationContainer>
<Drawer.Navigator
screenOptions={{
drawerStyle: {
backgroundColor: "white",
zIndex: 100,
},
drawerPosition: "right",
}}
>
{isLoggedIn ? (
<Drawer.Screen
name="ProtectedStack"
ponent={ProtectedStack}
options={{ header: () => <Header /> }}
/>
) : (
<Drawer.Screen
name="PublicStack"
ponent={PublicStack}
options={{ header: () => <Header /> }}
/>
)}
{/* This screen can be accessible even if when user is not authenticated */}
<Drawer.Screen
name="CocktailDetailScreen"
ponent={CocktailDetailScreen}
options={{ header: () => <Header /> }}
/>
</Drawer.Navigator>
</NavigationContainer>
);
};
This is reference, refactor and structure navigation your requirements.
Explore more at https://reactnavigation/docs/nesting-navigators/#navigator-specific-methods-are-available-in-the-navigators-nested-inside
My implementation was the following:
import { NavigationContainer } from '@react-navigation/native'
import { createNativeStackNavigator } from '@react-navigation/native-stack'
import { createDrawerNavigator } from '@react-navigation/drawer'
import * as React from 'react'
import LandingScreen from '../screens/LandingScreen'
import LoginScreen from '../screens/LoginScreen'
import RegisterScreen from '../screens/RegisterScreen'
import HomeScreen from '../screens/HomeScreen'
import ProfileScreen from '../screens/ProfileScreen'
import CocktailDetailScreen from '../screens/CocktailDetailScreen'
import PublishRecipeScreen from '../screens/PublishRecipeScreen'
import FavoritesScreen from '../screens/FavoritesScreen'
import PublishedRecipesScreen from '../screens/PublishedRecipesScreen'
import Header from '../ponents/Header'
import { RootStackParamList } from '../types'
export default function Navigation() {
const Stack = createNativeStackNavigator<RootStackParamList>()
const Drawer = createDrawerNavigator()
const isLoggedIn = false
const loginStack = () => (
<Stack.Navigator >
<Stack.Screen name='LandingScreen' ponent={LandingScreen} options={{headerShown: false}} />
<Stack.Screen name='LoginScreen' ponent={LoginScreen} options={{headerShown: false}} />
<Stack.Screen name='RegisterScreen' ponent={RegisterScreen} options={{headerShown: false}} />
</Stack.Navigator>
)
return (
<NavigationContainer>
<Drawer.Navigator screenOptions={{
drawerStyle: { backgroundColor: 'white' },
drawerPosition: 'right'
}}>
{!isLoggedIn ? (
<Stack.Screen
name="PublicStack"
ponent={loginStack}
options={{headerShown: false}}
/> )
:
(<>
<Drawer.Screen name='Search cocktails' ponent={HomeScreen} options={{ header: () => <Header/> }} />
<Drawer.Screen name='Profile' ponent={ProfileScreen} options={{ header: () => <Header/> }} />
<Drawer.Screen name='Publish a recipe' ponent={PublishRecipeScreen} options={{ header: () => <Header/> }} />
<Drawer.Screen name='Favorites' ponent={FavoritesScreen} options={{ header: () => <Header/> }} />
<Drawer.Screen name='Published recipes' ponent={PublishedRecipesScreen} options={{ header: () => <Header/> }} />
<Drawer.Screen name='Log out' ponent={LandingScreen} options={{ header: () => <Header/> }} />
<Drawer.Screen name='CocktailDetailScreen' ponent={CocktailDetailScreen} options={{
header: () => <Header/>,
drawerLabel: () => null,
title: undefined
}} />
</>
)}
</Drawer.Navigator>
</NavigationContainer>
)
}
I made the drawer navigator the main navigator, and made a different stack navigator just for the landing, register and login pages.
Within the drawer, I have this separate stack navigator as a child screen and passing it the stack navigator as the ponent.
The drawer screens remain the same as I had them before, except now CocktailDetailScreen is a child of drawer navigator too and thanks to that I can now action on it. Since I don't want that screen to be accessible through the navigator menu, I just don't render it there using
drawerLabel: () => null, title: undefined
本文标签: javascriptReact native drawer navigator not openingStack Overflow
版权声明:本文标题:javascript - React native drawer navigator not opening - Stack Overflow 内容由网友自发贡献,该文观点仅代表作者本人, 转载请联系作者并注明出处:http://www.betaflare.com/web/1744666916a2618588.html, 本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌抄袭侵权/违法违规的内容,一经查实,本站将立刻删除。
发表评论