React Native App - react-navigation v5 can't unmount on blur - react-native

I need screen to unmount whenever it goes out of focus. I am using a custom drawer and using props unmountOnBlur={true} and options={{unmountOnBlur: true} but its not working. What am i doing wrong or is there another way to accomplish this? I appreciate any help. Here is the relevant code:
<Drawer.Navigator drawerContent={(props) => <CustomDrawer {...props} />}>
<Drawer.Screen
name='Client Profile'
component={ProfileStackNavigator}
unmountOnBlur={true}
options={{unmountOnBlur: true}}
/>
</Drawer.Navigator>
Here is code on CustomDrawer.js :
<DrawerContentScrollView {...props} >
<DrawerItem
label='Profile'
onPress={() => props.navigation.navigate('Client Profile')}
unmountOnBlur={true}
options={{unmountOnBlur: true}}
/>
</DrawerContentScrollView>

Related

How to make drawerContentOptions work in React navigation 6.x

I don't know how to style my drawer with React navigation 6.x. They say to replace it with 'screenOptions' but it doesn't work. Here is my code:
<NavigationContainer>
<Drawer.Navigator
initialRouteName="Home"
screenOptions={{
activeTintColor:"blue",
itemStyle:{marginTop:20},
labelStyle:{fontSize:30},
style:{backgroundColor:'purple'}
}}>
<Drawer.Screen name="Home" component={Home}/>
<Drawer.Screen
name="Users"
component={Users}
/>
</Drawer.Navigator>
</NavigationContainer>
How can i make it work with my styling? I am a beginner, thanks for your help and time.
you can reed here about options here
<Drawer.Navigator
screenOptions={{
//options for drawer
drawerLabel
drawerIcon
drawerActiveTintColor
drawerActiveBackgroundColor
drawerInactiveTintColor
drawerInactiveBackgroundColor
drawerItemStyle
drawerLabelStyle
drawerContentContainerStyle
drawerContentStyle
drawerStyle
}}
>
{/* screens */}
</Drawer.Navigator>

React Navigation 6.x pressing back button takes you back to initial screen

I have just moved from React Native 5.x to 6.x and now my Navigation stack is giving me issues. When I navigate a few screens deep in my drawer navigator, and then press the back button on android (haven't tried IOS yes), it leads me right back to my first screen. My Navigation stack is as follows
<NavigationContainer theme={MyTheme}>
<Drawer.Navigator
initialRouteName="NewsFeed"
drawerContent={(props) => <SideNav {...props} />}
screenOptions={{ headerShown: true, header: (options) => <TopNav options={options} /> }}
>
<Drawer.Screen name="NewsFeed" component={NewsFeedScreen} />
<Drawer.Screen name="Post" component={PostScreen} />
<Drawer.Screen name="Users" component={UsersScreen} />
<Drawer.Screen name="User" component={UserScreen} />
...
</Drawer.Navigator>
</NavigationContainer>
I'm unsure what the issue is and haven't found any answers anywhere. Some say to wrap each screen in it's Stack navigator, others say it's a bad idea.
I am not sure if this is what you are asking for, but as for changes listed in the React Navigation Upgrading from 5.x help page:
The default value for backBehavior is now firstRoute for tabs and
drawer
and then:
To preserve old behavior, you can pass backBehavior="history" prop
to the navigators
So you can properly set backBehavior prop in your code like below:
<NavigationContainer theme={MyTheme}>
<Drawer.Navigator
initialRouteName="NewsFeed"
drawerContent={(props) => <SideNav {...props} />}
screenOptions={{ headerShown: true, header: (options) => <TopNav options={options} /> }}
backBehavior="history" // <-- ADDED PROP
>
...
</NavigationContainer>

How can I create a custom navigation drawer in react-native using react-navigation v5?

I am looking to create a custom drawer navigator with a few expandable list views with a few hidden routes.
E.g.
Home
Main1
Hidden 1
hid a
hid b
Hidden 2
hid a
hid b
Where hid a and hid b would be hidden behind hidden 1 or hidden 2. When hidden 1 or hidden 2 is clicked or touched the hid a/hid b would be displayed.
This is what I have so far --
Main.js:
export default function MainScreen({ navigation }){
return (
<NavigationContainer>
<Drawer.Navigator initialRouteName='Home' drawerContent={props => <Menu {... props} />}>
<Drawer.Screen name=".." options={{drawerIcon: config => <Icon name=".." size={22} color="#000"></Icon>}} component={HomeScreen} />
<Drawer.Screen name="Ex1" component={Ex1} />
<Drawer.Screen name="Ex2" component={Ex2} />
<Drawer.Screen name="Ex3" component={Ex3} />
<Drawer.Screen name="Ex4" component={Ex4} />
<Drawer.Screen name="Ex5" component={Ex5} options={{
title:"..",
drawerIcon: config => <Icon
size={22}
name='..'></Icon>
}} />
</Drawer.Navigator>
</NavigationContainer>
)
}
Menu.js:
const Menu = (props) => {
return (
<SafeAreaView style={{flex: 1}}>
<DrawerContentScrollView {...props}>
<DrawerItemList {...props} />
</DrawerContentScrollView>
</SafeAreaView>
);
};
And I'm looking to split out DrawerItemList so I can display a few of my routes within a dropdown.
Much of the code in the samples above has been sanitised because a lot of it is commercially sensitive but I can assure you my component names etc are much better in the actual code.
Any suggestions or comments would be much appreciated.
I have just started working with react-native so bare with me.
If you need any more info, please don't hesitate to comment and ask.
Thanks in advance.
Solution was to use #eliav2/react-native-collapsible-view for the collapsible view with DrawerItems inside.

Disabling gesture in react-navigation 5

I'm creating a project and Initially, it has two stack screens. SettingScreen and ChangePasswordScreen and the one drawer.
export const SettingStackScreen = ({ navigation }) => (
<SettingStack.Navigator>
<SettingStack.Screen
name="Settings"
component={SettingScreen}
/>
<SettingStack.Screen
name="ChangePassword"
component={ChangePasswordScreen}
/>
</SettingStack.Navigator>
);
app.js
<Drawer.Navigator
drawerContent={(props) => <DrawerContent {...props} />}
>
<Drawer.Screen name="Settings" component={SettingStackScreen} />
</Drawer.Navigator>
using this code Drawer is accessible on both screen but I want to access drawer only first screen of SettingStackScreen not on others screen.
I tried gestureEnabled but it disabling the drawer swipe gesture in the both screen.
give this a go:
<Drawer.Navigator
drawerContent={(props) => <DrawerContent {...props} />
edgeWidth={-1} // don't allow slide-to-open
>
<Drawer.Screen name="Settings" component={SettingStackScreen} />
</Drawer.Navigator>
from the docs:
edgeWidth
Allows for defining how far from the edge of the content view the
swipe gesture should activate.
This is not supported on Web.
If you go with this solution you're gonna need a burger menu or something that opens the drawer menu, something like:
<BurgerMenuButton onPress={() => navigation.toggleDrawer()} />

Got both 'component' and 'children' props for the screen 'Search'. You must only pass one of them

I work on a react-native app and this project used react-navigation 4.x to navigate around the app.
I recently upgraded the project to 5.x of react-navigation and while trying to upgrade I ran into a problem. The problem is that my project has both a FooterNavigator and a DrawerNavigator, they both call on the same component.
We already figured out a way to fix the problem in react-navigation 4.x but the new version of react-navigation requires a name and a component for each Screen. Is there any way for me to have both the navigators at the same time or is it better to downgrade?
Image of the error
This is my FooterNavigator
const Tab = createBottomTabNavigator();
export const FooterNavigator = () => {
return (
<Tab.Navigator>
<Tab.Screen name="Search" component={Search}>
<Button>
<Icon name="magnify" type="MaterialCommunityIcons"/>
<Text style={footerStyle.footerText}>Zoeken</Text>
</Button>
</Tab.Screen>
<Tab.Screen name="Count" component={Count}>
<Button>
<Icon name="counter" type="MaterialCommunityIcons"/>
<Text style={footerStyle.footerText}>Tellen</Text>
</Button>
</Tab.Screen>
<Tab.Screen name="Identify" component={Identify}>
<Button>
<Icon name="file-question" type="MaterialCommunityIcons"/>
<Text style={footerStyle.footerText}>Herken</Text>
</Button>
</Tab.Screen>
<Tab.Screen name="Program" component={Program}>
<Button>
<Icon name="chip" type="MaterialCommunityIcons"/>
<Text style={footerStyle.footerText}>Wijzig</Text>
</Button>
</Tab.Screen>
</Tab.Navigator>
)
}
And this is my DrawerNavigator
export const RootNavigator = () => {
let DrawerScreens = [];
Routes.forEach(function (route) {
DrawerScreens.push(<Drawer.Screen name={route.name} component={route.component}/>)
});
return (
<Drawer.Navigator>
{DrawerScreens}
</Drawer.Navigator>
)
}
They are both called and rendered in my Layout.js
render() {
return (
<NavigationContainer>
<RootNavigator />
<FooterNavigator/>
</NavigationContainer>
)
}
Many thanks in advance !!
use this
<Stack.Screen name="Home" component={HomeScreen} />
instead of this
<Stack.Screen name="Home" component={HomeScreen}> </Stack.Screen>
solve your problem
<NavigationContainer>
<Stack.Navigator initialRouteName="Home">
<Stack.Screen name="Home" component={HomeScreen}/>
<Stack.Screen name="Details" component={DetailScreen} />
</Stack.Navigator>
</NavigationContainer>
Just remove component prop from stack screen. if you are passing custom values through navigation stack
I get this error when I use a <Stack.Screen> and provide a component and a child to it, as the error mentions.
<Stack.Screen name="Home" component={Home}>
{props => <Home {...props} sampleProperty="XXXXXXXX" />}
</Stack.Screen>
removing this bit component={Home} on line1 fixes the error.