How to create a menu Icon in a drawer navigation? React Native - react-native

I nested a Drawer Navigator in a Stack Navigator, it works well and opens when I swipe it, I want to put a Menu Icon above it when it's pressed the drawer gets open. Every method I tried always ends up with navigation can't be found error.
Here's my code:
export class App extends Component {
.....
function DrawerNav() {
return (
<Drawer.Navigator
drawerType="front"
initialRouteName="Main" drawerPosition="right">
<Drawer.Screen name="Main" component={MainScreen} />
<Drawer.Screen name="Wallet" component={WalletScreen} />
<Drawer.Screen name="Appointments" component={Appointments} />
</Drawer.Navigator>
);}
return (
<Provider store={store}>
<NavigationContainer>
<Stack.Navigator initialRouteName="Menu">
<Stack.Screen name="Menu" component={DrawerNav} />
<Stack.Screen name="Add" component={AddScreen} navigation={this.props.navigation}/>
<Stack.Screen name="Save" component={SaveScreen} navigation={this.props.navigation}/>
</Stack.Navigator>
</NavigationContainer>
</Provider>
)}}
I want to open and close the drawer when I press on this icon:
<MaterialIcons name='menu' size={28} onPress={??} />

<MaterialIcons name='menu' size={28} onPress={()=>this.props.navigation.openDrawer()} />

Related

How to navigate to a screen which is not on the <Tab.Navigator> in React-Nativ?

I have a <Tab.Navigator> and it has four <Tab.Screen> elements. What i try to do is, to press a button inside a specific <Tab.Screen> and open an another screen on top of it. But i don't want this another screen to have a <Tab.Screen> navigator in the <Tab.Navigator> bar.
I thought maybe there's an option to hide, make invisible a <Tab.Screen> but i couldn't find any documentation about it.
Is it possible to achieve this ?
According the official doc. You can reorganize your navigation and put the bottom tabs navigator inside the stack navigator like this
function HomeTabs() {
return (
<Tab.Navigator> // Here you can also navigate to both Profile and Settings
<Tab.Screen name="Home" component={Home} />
<Tab.Screen name="Feed" component={Feed} />
<Tab.Screen name="Notifications" component={Notifications} />
</Tab.Navigator>
);
}
function App() {
return (
<Stack.Navigator>
<Stack.Screen name="Home" component={HomeTabs} />
<Stack.Screen name="Profile" component={Profile} /> // Here you won't have any tabs
<Stack.Screen name="Settings" component={Settings} /> // Here neither
</Stack.Navigator>
);
}
You have to nest navigators with the stack navigator as the outer navigator and the tab navigator as the inner navigator:
https://reactnavigation.org/docs/nesting-navigators
You have to reorganize your navigation structure , as documentation describe https://reactnavigation.org/docs/hiding-tabbar-in-screens
Let's say we have 5 screens: Home, Feed, Notifications, Profile and Settings, and your navigation structure looks like this:
function HomeStack() {
return (
<Stack.Navigator>
<Stack.Screen name="Home" component={Home} />
<Stack.Screen name="Profile" component={Profile} />
<Stack.Screen name="Settings" component={Settings} />
</Stack.Navigator>
);
}
function App() {
return (
<Tab.Navigator>
<Tab.Screen name="Home" component={HomeStack} />
<Tab.Screen name="Feed" component={Feed} />
<Tab.Screen name="Notifications" component={Notifications} />
</Tab.Navigator>
);
}
With this structure, when we navigate to the Profile or Settings screen, the tab bar will still stay visible over those screens.
But if we want to show the tab bar only on the Home, Feed and Notifications screens, but not on the Profile and Settings screens, we'll need to change the navigation structure. The easiest way to achieve this is to nest the tab navigator inside the first screen of the stack instead of nesting stack inside tab navigator:
function HomeTabs() {
return (
<Tab.Navigator>
<Tab.Screen name="Home" component={Home} />
<Tab.Screen name="Feed" component={Feed} />
<Tab.Screen name="Notifications" component={Notifications} />
</Tab.Navigator>
);
}
function App() {
return (
<Stack.Navigator>
<Stack.Screen name="Home" component={HomeTabs} />
<Stack.Screen name="Profile" component={Profile} />
<Stack.Screen name="Settings" component={Settings} />
</Stack.Navigator>
);
}
After re-organizing the navigation structure, now if we navigate to the Profile or Settings screens, the tab bar won't be visible over the screen anymore.

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 Native Redux conditional rendering

I'm trying to render 2 different screens in my App based on the redux store status.
const App = () => {
return (
<Provider store={store}>
<NavigationContainer ref={navigationRef}>
{store.getState().auth.id ? (
<Home />
) : (
<Stack.Navigator screenOptions={HeaderStyles}>
<Stack.Screen
name='Splash'
component={Splash}
options={{ headerShown: false }}
/>
<Stack.Screen name='SignUp' component={SignUp} />
<Stack.Screen name='Login' component={Login} />
</Stack.Navigator>
)}
</NavigationContainer>
</Provider>
);
};
At startup store.getState().auth.id is undefined, so the app correctly shows the Splash screen. In this screen, I set the auth.id in the store but the App doesn't rerender and stays in the Splash screen. If I save any source file without changing anything, if forces a rerender and I get correctly routed to Home.
How can I force the ternary operator to be evalued again when the store changes?
At your file, store is imported from the file it is creating in, and not injected through props (mapState || useSelector).
Because React re-render built on changes in props || state, the component doesn't know it should render again.
The easy way to go around the issue is to declare the conditional part at the child component and inject the redux state properly.
<Provider store={store}>
<NavigationContainer ref={navigationRef}>
<Navigator />
</NavigationContainer>
</Provider>
....
const Navigator = () => {
let { id } = useSelector(state => state.auth)
return !!id ? (
<Home />
) : (
<Stack.Navigator screenOptions={HeaderStyles}>
<Stack.Screen
name='Splash'
component={Splash}
options={{ headerShown: false }}
/>
<Stack.Screen name='SignUp' component={SignUp} />
<Stack.Screen name='Login' component={Login} />
</Stack.Navigator>
)
}

React navigation drawer v5x

I have tried to use minSwipeDistance property of drawer navigator.But It gives me error like Inviolant object.After trying a lot I didn't know what to do.Anyone can help me?
<NavigationContainer ref={navigationRef}>
<Loader loading={this.state.loading} close={()=>{}} />
<Drawer.Navigator
drawerStyle={{
width:Dimensions.get('window').width,
}} drawerContent={ ()=>{return(<MenuDrawer cats={this.state.cat_list} />)}}>
screenOptions={{
minSwipeDistance:0.5
}}
<Drawer.Screen
name="Main"
component={MainComponent}
/>
</Drawer.Navigator>
</NavigationContainer>

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.