'React navigation - react native - How to block drawer in Stack Navigator nested inside Drawer Navigator?
In my react native app I have a stack navigator nested inside a drawer navigator. I want the drawer to be disabled in the stack navigator pages. I'm using react navigation 6.
In the docs (https://reactnavigation.org/docs/drawer-navigator/#options) I see there are two options for this: gestureEnabled and swipeEnabled. But these can only be used in drawer screens, not in stack screens like my case.
My code is as following:
const Stack = createNativeStackNavigator<RootStackParamList>()
const Drawer = createDrawerNavigator<RootTabParamList>()
const loginStack = () => (
<Stack.Navigator >
<Stack.Screen name='LandingScreen' component={LandingScreen} options={{headerShown: false}} />
<Stack.Screen name='LoginScreen' component={LoginScreen} options={{headerShown: false}} />
<Stack.Screen name='RegisterScreen' component={RegisterScreen} options={{headerShown: false}} />
</Stack.Navigator>
)
return (
<NavigationContainer>
<Drawer.Navigator
screenOptions={{
drawerStyle: { backgroundColor: 'white' },
drawerPosition: 'right'
}}>
{!user ? (
<Drawer.Screen
name='PublicStack'
component={loginStack}
// options={{headerShown: false}}
options={({ route }) => {
const routeName = getFocusedRouteNameFromRoute(route)
if (routeName === 'LandingScreen' || routeName === 'LoginScreen' || routeName === 'RegisterScreen') return ({swipeEnabled: false, gestureEnabled: false})
else return ({swipeEnabled: true, gestureEnabled: true})
}}
/> )
:
(<>
<Drawer.Screen name='Search cocktails' component={HomeScreen} options={{ header: () => <Header/> }} />
<Drawer.Screen name='Profile' component={ProfileScreen} initialParams={{ userParam: null }} options={{ header: () => <Header/> }} />
<Drawer.Screen name='Publish a recipe' component={PublishRecipeScreen} options={{ header: () => <Header/> }} />
<Drawer.Screen name='Favorites' component={FavoritesScreen} options={{ header: () => <Header/> }} />
<Drawer.Screen name='Published recipes' component={PublishedRecipesScreen} options={{ header: () => <Header/> }} />
<Drawer.Screen name='Log out' component={CustomDrawerContent} options={{ header: () => <Header/> }} />
<Drawer.Screen name='CocktailDetailScreen' component={CocktailDetailScreen} options={{
header: () => <Header/>,
drawerLabel: () => null,
title: undefined
}} />
</>
)}
</Drawer.Navigator>
</NavigationContainer>
)
}
I've tried setting the mentioned options directly on the loginStack drawer screen, like:
<Drawer.Screen
name='PublicStack'
component={loginStack}
options={{swipeEnabled: false, gestureEnabled: false}}}
/>
But didn't work.
I've also seen this answer (How to disable drawer inside Stack Navigator nested inside Drawer Navigator?) and tried to implement something similar (what my code looks like right now) but still didn't work.
Full code can be found here: https://github.com/coccagerman/mixr
Thanks!
Solution 1:[1]
I was stuck with the same thing these days. I didn't find a solution to use getFocusedRouteNameFromRoute(route) and took a different approach.
The first thing is block the Drawer in the whole app:
<Drawer.Navigator screenOptions = {{ swipeEnabled: false }}>
<Drawer.Screen name="Screen1" component={StackScreen1} />
<Drawer.Screen name="Screen2" component={StackScreen2} />
</Drawer.Navigator>
Then, you enable the Drawer on the screens you need, like this:
useFocusEffect(
useCallback((() => {
// From a Stack screen, the Drawer is accessed.
const parent = navigation.getParent()
parent?.setOptions({ swipeEnabled: true })
// It returns to the initial state.
return () => parent?.setOptions({ swipeEnabled: false })
}, [navigation])
)
In case you have to enable the Drawer on many screens, it can be done the other way around. Enable the Drawer in the whole app, and block it only in the desired ones.
I know that maybe it's not the best solution but I hope it helps you. Saludos!
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
| Solution | Source |
|---|---|
| Solution 1 |
