To attain drawer navigation menu on the right in react native - react-native

When i am adding selected code then its showing undefined object (evaluating 'route.routeName').
Navigation drawer is by default on the left. How to attain it on right side ?
import React, { Component } from "react";
import { Platform, StyleSheet, Text, View } from "react-native";
import { DrawerNavigator } from "react-navigation";
import ScreenFirst from "./src/ScreenFirst";
import ScreenTwo from "./src/ScreenTwo";
const DrawerExample = DrawerNavigator(
{
ScreenFirst: { screen: ScreenFirst },
ScreenTwo: { screen: ScreenTwo }
},
{
drawerPosition: "right",
drawerWidth: 100
}
);
export default DrawerExample;

if you are using navigation 3.x you will need to import these guys
import {createDrawerNavigator, createAppContainer} from 'react-navigation'
then try this one:
const DrawerExample = DrawerNavigator(
{
ScreenFirst: { screen: ScreenFirst },
ScreenTwo: { screen: ScreenTwo }
},
{
drawerPosition: "right",
drawerWidth: 100
}
);
const MyApp = createAppContainer(DrawerExample);
export default MyApp

For who comes from React Navigation V5. Just call drawerPosition like below:
<Drawer.Navigator initialRouteName="SignIn" drawerPosition="right">
<Drawer.Screen name="welcome" component={Welcome} />
</Drawer.Navigator>

import {DrawerActions} from '#react-navigation/native';
<Drawer.Navigator screenOptions={{ drawerPosition: 'right', }}> <Drawer.Screen name="Home" component={Home} options={{ headerStyle: { backgroundColor: 'orange', }, headerTintColor: 'black', headerLeft:false, headerRight: () => ( <TouchableOpacity onPress={() => navigation.dispatch(DrawerActions.openDrawer())}> ), }} /> <Drawer.Screen name="Standings" component={Standings} /> </Drawer.Navigator>
it worked for me

For 6.x
<NavigationContainer>
<Drawer.Navigator initialRouteName="Home" screenOptions={{drawerPosition:"right"}}
>
<Drawer.Screen name="Home" component={HomeScreen} />
<Drawer.Screen name="Notifications" component={NotificationsScreen} />
</Drawer.Navigator>
</NavigationContainer>

In React Navigation version 5, add the drawerPosition prop with value right in your Drawer Navigator.
<Drawer.Navigator drawerPosition="right">
<Drawer.Screen name="Feed" component={Feed} />
<Drawer.Screen name="Article" component={Article} />
</Drawer.Navigator>
Read here for the official docs.

Related

React drawer Navigation lags while opening

I am nesting a drawer navigation on top of a stack navigator. It works, but the problem is that it lags excessively while opening the drawer. What could be the issue here?
import React, { useEffect, useState } from "react";
import CartIcon from "../CartIcon";
import Home from "../../screens/Home";
import Orders from "../../screens/Orders";
import ProductsScreen from "../../screens/ProductsScreen";
import Cart from "../../screens/Cart";
import { createNativeStackNavigator } from "#react-navigation/native-stack";
import HomeHeader from "../HomeHeader";
import OrdersDetails from "../../screens/OrdersDetails";
import { createDrawerNavigator } from "#react-navigation/drawer";
const Drawer = createDrawerNavigator()
const Stack = createNativeStackNavigator();
My drawer navigator here
const HomeScreen=()=> {
return (
<Drawer.Navigator>
<Drawer.Screen name="Home" component={Home} options={() => ({
title: "BarPoint",
headerRight: () => <HomeHeader />,
})} />
</Drawer.Navigator>
);
}
stack navigator here
const AppStack = () => {
return (
<Stack.Navigator>
<Stack.Screen
name="HomeScreen"
component={HomeScreen}
options={{ headerShown: false }}
/>
<Stack.Screen
name="ProductsScreen"
component={ProductsScreen}
options={({ navigation }) => ({
title: "Products",
headerRight: () => <CartIcon navigation={navigation} />,
})}
/>
<Stack.Screen name="Cart" component={Cart} />
<Stack.Screen name="Orders" component={Orders} />
<Stack.Screen name="OrdersDetails" component={OrdersDetails} />
</Stack.Navigator>
);
};
export default AppStack;
Add useLegacyImplementation in Drawer.Navigator and compile.
const HomeScreen=()=> {
return (
<Drawer.Navigator
useLegacyImplementation //<- Add here
>
<Drawer.Screen name="Home" component={Home} options={() => ({
title: "BarPoint",
headerRight: () => <HomeHeader />,
})} />
</Drawer.Navigator>
);
}
It occurred an Error to me by adding useLegacyImplementation.
Here is my code.Also,I can't touch off my sidebar by navigation.openDrawer
my devices: xcode13 react-navigation6.x
import React ,{Component}from 'react';
import { Button, View ,Text,StyleSheet} from 'react-native';
import { createDrawerNavigator } from '#react-navigation/drawer';
const Drawer=createDrawerNavigator()
//two function
function HomeScreen(prop){
return(
<View style={styles.container}>
<Text style={styles.text}>Home Screen</Text>
<Button title={"Open Drawer"} onPress={()=>prop.navigation.openDrawer()}/>
<Button title={"Toggle Drawer"} onPress={()=>prop.navigation.toggleDrawer()}/>
</View>
)
}
function NewsScreen(prop){
return(
<View style={styles.container}>
<Text style={styles.text}>News Screen</Text>
<Button title={"jump to Home"} onPress={()=>prop.navigation.navigate('Home')}/>
</View>
)
}
export default class index extends Component{
render(){
return(
<Drawer.Navigator useLegacyImplementation={true} >
<Drawer.Screen name="Home" component={HomeScreen} />
<Drawer.Screen name="News" component={NewsScreen} />
</Drawer.Navigator>
)
}
}
const styles=StyleSheet.create({
container:{
flex:1,
justifyContent:'center',
alignItems: 'center',
},
text:{
fontSize:40
}
})

Combining a stack navigator with a drawer navigator in react native

So I'm new to react native and react navigation.
I'm building an app that will have 7 main screens:
HomeScreen, ProfileScreen, CocktailDetailScreen and PublishRecipeScreen (which I want to be able to access through a drawer navigator).
LandingScreen, LoginScreen and RegisterScreen (which I don't want to show in the drawer navigator. I just want to show the LandingScreen when the user isn't logged in, and either of the other if the user want's to log in or register).
I've been able to put up a stack navigator that works fine, but I don't understand how to combine this with the drawer navigator I want. I've tried different approaches but I get errors like:
The action 'OPEN_DRAWER' was not handled by any navigator.
Is your screen inside a Drawer navigator?
or
Uncaught Error: Looks like you have nested a 'NavigationContainer' inside another. Normally you need only one container at the root of the app, so this was probably an error. If this was intentional, pass 'independent={true}' explicitly. Note that this will make the child navigators disconnected from the parent and you won't be able to navigate between them.
This is my code so far.
App.tsx
import { SafeAreaProvider } from 'react-native-safe-area-context'
import useCachedResources from './hooks/useCachedResources'
import Navigation from './navigation'
export default function App() {
const isLoadingComplete = useCachedResources()
if (!isLoadingComplete) {
return null
} else {
return (
<SafeAreaProvider>
<Navigation />
</SafeAreaProvider>
)
}
}
(navigation) index.tsx
import { NavigationContainer } from '#react-navigation/native'
import { createNativeStackNavigator } from '#react-navigation/native-stack'
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 Header from '../components/Header'
import DrawerNavigator from '../components/DrawerNavigator'
import { RootStackParamList } from '../types'
export default function Navigation() {
const Stack = createNativeStackNavigator<RootStackParamList>()
return (
<NavigationContainer>
<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.Screen name='HomeScreen' component={HomeScreen} options={{ header: () => <Header/> }} />
<Stack.Screen name='ProfileScreen' component={ProfileScreen} options={{ header: () => <Header/> }} />
<Stack.Screen name='CocktailDetailScreen' component={CocktailDetailScreen} options={{ header: () => <Header/> }} />
<Stack.Screen name='PublishRecipeScreen' component={PublishRecipeScreen} options={{ header: () => <Header/> }} />
</Stack.Navigator>
</NavigationContainer>
)
}
header.tsx
import React from 'react'
import { useNavigation } from '#react-navigation/native'
import { useDrawerStatus } from '#react-navigation/drawer'
import { DrawerActions } from '#react-navigation/native'
import { StyleSheet, Text, View } from 'react-native'
import { AntDesign } from '#expo/vector-icons'
const Header = () => {
const navigation = useNavigation()
return (
<View style={styles.container}>
<Text style={styles.title} onPress={() => navigation.navigate('RegisterScreen')}>Mixr</Text>
<View style={styles.iconContainer} >
<AntDesign name='user' style={styles.icon} size={30} color='white' onPress={() => navigation.dispatch(DrawerActions.openDrawer())} />
</View>
</View>
)
}
const styles = StyleSheet.create({
container: {
flexDirection: 'row',
alignItems: 'center',
justifyContent: 'space-between',
backgroundColor: '#E51C27',
alignSelf: 'stretch'
},
title: {
fontSize: 40,
fontWeight: 'bold',
marginTop: 6,
marginBottom: 6,
marginLeft: 10
},
iconContainer: {
backgroundColor: 'black',
borderBottomLeftRadius: 50,
borderBottomRightRadius: 50,
borderTopLeftRadius: 50,
borderTopRightRadius: 50,
marginRight: 10
},
icon: {
padding: 5
}
})
export default Header
DrawerNavigator.tsx
import React from 'react'
import { createDrawerNavigator, useDrawerStatus } from '#react-navigation/drawer'
import { NavigationContainer } from '#react-navigation/native'
import HomeScreen from '../screens/HomeScreen'
import ProfileScreen from '../screens/ProfileScreen'
import CocktailDetailScreen from '../screens/CocktailDetailScreen'
import PublishRecipeScreen from '../screens/PublishRecipeScreen'
const DrawerNavigator = () => {
const Drawer = createDrawerNavigator()
return (
<NavigationContainer>
<Drawer.Navigator>
<Drawer.Screen name='HomeScreen' component={HomeScreen} />
<Drawer.Screen name='ProfileScreen' component={ProfileScreen} />
<Drawer.Screen name='CocktailDetailScreen' component={CocktailDetailScreen} />
<Drawer.Screen name='PublishRecipeScreen' component={PublishRecipeScreen} />
</Drawer.Navigator>
</NavigationContainer>
)
}
export default DrawerNavigator
I want to show a header in all of this pages (HomeScreen, ProfileScreen, CocktailDetailScreen and PublishRecipeScreen) and from that header be able to open/close the drawer. I don't quite understand how to link the stack navigator with the drawer.
From a more theoretical point of view, I don't really understand the difference between the stack navigator, the drawer, and other options like tab or bottom navigators.
I mean, besides that the drawer navigator shows in a drawer and the bottom one shows at the bottom. Is there a conceptual difference between them?
Full code can be found here: https://github.com/coccagerman/mixr
I think I figured it out.
What I did is nest the drawer navigator within the stack navigator.
To do so, I passed the Drawer navigator as the component of each of the screens I wanted it to be in.
Like so:
(navigation) index.tsx
import { NavigationContainer } from '#react-navigation/native'
import { createNativeStackNavigator } from '#react-navigation/native-stack'
import * as React from 'react'
import LandingScreen from '../screens/LandingScreen'
import LoginScreen from '../screens/LoginScreen'
import RegisterScreen from '../screens/RegisterScreen'
import Header from '../components/Header'
import DrawerNavigator from '../components/DrawerNavigator'
import { RootStackParamList } from '../types'
export default function Navigation() {
const Stack = createNativeStackNavigator<RootStackParamList>()
return (
<NavigationContainer>
<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.Screen name='HomeScreen' component={DrawerNavigator} options={{ header: () => <Header/> }} />
<Stack.Screen name='ProfileScreen' component={DrawerNavigator} options={{ header: () => <Header/> }} />
<Stack.Screen name='CocktailDetailScreen' component={DrawerNavigator} options={{ header: () => <Header/> }} />
<Stack.Screen name='PublishRecipeScreen' component={DrawerNavigator} options={{ header: () => <Header/> }} />
</Stack.Navigator>
</NavigationContainer>
)
}
And in the drawer navigator I assign the corresponding screen component to each screen:
DrawerNavigator.tsx
import React from 'react'
import { createDrawerNavigator } from '#react-navigation/drawer'
import HomeScreen from '../screens/HomeScreen'
import ProfileScreen from '../screens/ProfileScreen'
import CocktailDetailScreen from '../screens/CocktailDetailScreen'
import PublishRecipeScreen from '../screens/PublishRecipeScreen'
const DrawerNavigator = () => {
const Drawer = createDrawerNavigator()
return (
<Drawer.Navigator>
<Drawer.Screen name='Home' component={HomeScreen} options={{headerShown: false}} />
<Drawer.Screen name='Profile' component={ProfileScreen} options={{headerShown: false}} />
<Drawer.Screen name='CocktailDetail' component={CocktailDetailScreen} options={{headerShown: false}} />
<Drawer.Screen name='PublishRecipe' component={PublishRecipeScreen} options={{headerShown: false}} />
</Drawer.Navigator>
)
}
export default DrawerNavigator
I still find this a bit confusing though, and I guess there's probably a simpler way to write this.
Useful resources I've found on this topic:
https://reactnavigation.org/docs/nesting-navigators/
https://blog.waldo.io/combining-navigators-in-react-navigation/

React native header left button left margin

I am trying to add left padding or margin to the header left icon which is a back button on the login page. Below is my code, I tried adding headerLeftContainerStyle but it is not working. On the home page the menu icon is perfectly set with a padding from the left, but on the login page the back button is attached with the left side of the screen.
/**
* Sample React Native App
* https://github.com/facebook/react-native
*
* #format
* #flow strict-local
*/
import 'react-native-gesture-handler';
import React from 'react';
import { NavigationContainer } from '#react-navigation/native';
import { createDrawerNavigator } from '#react-navigation/drawer';
import Colors from './src/settings/Colors';
import {StyleSheet, StatusBar, Text} from 'react-native';
import Icon from 'react-native-vector-icons/FontAwesome';
import { DrawerContent } from './src/navigation/DrawerContent';
import { TabContent } from './src/navigation/TabContent';
import Login from './src/screens/auth/Login';
import Feedback from './src/screens/Feedback';
const Drawer = createDrawerNavigator();
const App = () => {
return (
<NavigationContainer>
<StatusBar barStyle="dark-content" backgroundColor={Colors.primary} />
<Drawer.Navigator drawerContent={props => <DrawerContent {...props} />} screenOptions={{
headerShown: true,
headerTitleAlign: 'center',
headerStyle: styles.headerBackgroundColor,
headerTitleStyle: styles.headerTitleStyle,
}}>
{/* <Drawer.Screen name="home" component={TabContent} options={{ title: 'DevMuscles' }} /> */}
<Drawer.Screen name="Home" component={TabContent} />
<Drawer.Screen name="Feedback" component={Feedback} options={{ title: 'Feedback' }} />
<Drawer.Screen name="Login" component={Login} options={{
title: 'Login' ,
headerLeft: () => (
<Icon name="arrow-left" size={23} />
),
headerLeftContainerStyle: {
screenLeft: 50
},
}} />
</Drawer.Navigator>
</NavigationContainer>
);
};
export default App;
Fixed it using the below code.
import { HeaderBackButton } from '#react-navigation/stack';
headerLeft: (props) => (
<HeaderBackButton
{...props}
onPress={() => {
// Do something
}}
/>
),
Try to add styles manually to the Icon component.
<Icon name='' style={{ marginLeft: 10 }} />

Trying to make a Home Screen in React-Native

I am new to React-Native and I am trying to make a Home Page in my app and at the same time declare some components.
Here is the code I tried to implement
import React from "react";
import {createAppContainer} from '#react-navigation/native'
import {createStackNavigator} from '#react-navigation/stack'
import Buttons from "./Buttons.js"
import PlaylistScreen from "./react/screens/PlaylistScreen.js"
// const navigator = createStackNavigator (
// {
// ButtonsScreen: Buttons,
// Playlist: {
// screen: Playlist
// }
// },
// {
// initialRouteName:'ButtonsScreen',
// defaultNavigationOptions: {
// title:"App"
// }
// }
// );
const Stack = createStackNavigator();
function MyStack() {
return (
<Stack.Navigator
initialRouteName="Buttons"
headerMode="screen"
screenOptions={{
headerTintColor: 'white',
headerStyle: { backgroundColor: 'tomato' },
}}
>
<Stack.Screen
name="ButtonsScreen"
component={Buttons}
options={{
title: 'Awesome app',
}}
/>
<Stack.Screen
name="Playlist"
component={ {screen: PlaylistScreen}}
options={{
title: 'My profile',
}}
/>
</Stack.Navigator>
);
}
export default createAppContainer(Stack);
However, I have encounterd problems, giving me those errors:
enter image description here
Please help me, I would be very grateful. :)
https://reactnavigation.org/docs/stack-navigator
import { createStackNavigator } from '#react-navigation/stack';
const Stack = createStackNavigator();
function MyStack() {
return (
<Stack.Navigator>
<Stack.Screen name="Home" component={Home} />
<Stack.Screen name="Notifications" component={Notifications} />
<Stack.Screen name="Profile" component={Profile} />
<Stack.Screen name="Settings" component={Settings} />
</Stack.Navigator>
);
}
I have reformatted your code by wrapping your stack navigator inside navigation container and exported MyStack component to be like this:
import {NavigationContainer} from '#react-navigation/native';
const Stack = createStackNavigator();
function MyStack() {
return (
<NavigationContainer>
<Stack.Navigator
initialRouteName="Buttons"
headerMode="screen"
screenOptions={{
headerTintColor: 'white',
headerStyle: { backgroundColor: 'tomato' },
}}
>
<Stack.Screen
name="ButtonsScreen"
component={Buttons}
options={{
title: 'Awesome app',
}}
/>
<Stack.Screen
name="Playlist"
component={ {screen: PlaylistScreen}}
options={{
title: 'My profile',
}}
/>
</Stack.Navigator>
</NavigationContainer>
);
}
export default MyStack;

problem to give screenOptions to the DrawerNavigator

I was facing trouble using createDrawerNavigator. I was following there Docs and try to implement something like this:
import { createStackNavigator } from '#react-navigation/stack';
import { createDrawerNavigator } from '#react-navigation/drawer';
const MenuNavigator = createStackNavigator();
const HeaderOptions = {
headerStyle: {
backgroundColor: '#512DA8',
},
headerTintColor: '#fff',
headerTitleStyle: {
color: '#fff',
},
};
function MenuNavigatorScreen() {
return (
<MenuNavigator.Navigator
//initialRouteName
screenOptions={HeaderOptions}
>
//Screens
</MenuNavigator.Navigator>
);
}
const HomeNavigator = createStackNavigator();
function HomeNavigatorScreen() {
return (
<HomeNavigator.Navigator
//initialRouteName
screenOptions={HeaderOptions}
>
//Screen
</HomeNavigator.Navigator>
);
}
const MainNavigator = createDrawerNavigator();
function MainNavigatorDrawer() {
return (
<MainNavigator.Navigator
initialRouteName="Home"
drawerStyle={{
backgroundColor: '#D1C4E9',
}}
screenOptions={HeaderOptions} //Isn't it should be applied to all screen
>
<MainNavigator.Screen name="Home" component={HomeNavigatorScreen} />
<MainNavigator.Screen name="Menu" component={MenuNavigatorScreen} />
<MainNavigator.Screen name="About" component={component1} />
<MainNavigator.Screen name="Contact" component={component2} />
</MainNavigator.Navigator>
);
}
I got the header in the Home and Menu but in the About and Contact screen there is no header. I think screenOptions isn't working in the DrawerNavigator, then how to give them this options?
And one more thing, I realize that I repeat my code many times. Is there any better approach?
I heartily thank if anyone helps me to figure out this.
Ok, I solve the header issue by turning my component1 and component2 into a stackNavigator like:
const stack = createStackNavigator();
function AboutNavigatorScreen() {
return (
<stack.Navigator screenOptions={HeaderOptions}>
<stack.Screen name="About" component={component1} />
</stack.Navigator>
);
}
function ContactNavigatorScreen() {
return (
<stack.Navigator screenOptions={HeaderOptions}>
<stack.Screen name="Contact" component={component2} />
</stack.Navigator>
);
}
What I understand is "If I need to add any screenOptions in my component the turn it into a stacknagivator" which seem odd. Am I right or over-engineering my problem?
Good day, to implement the header on the site, you need to specify the screenOptions={{headerShown: true}}> in Driver.Navigator.
And then prescribe options
import React from 'react';
import {NavigationContainer} from '#react-navigation/native';
import {createDrawerNavigator} from '#react-navigation/drawer';
import {Home} from '../screens/Home'
import LeftBurgerMenu from "../components/LeftBurgerMenu";
const Drawer = createDrawerNavigator();
export const AppNavigation = () => {
return (
<NavigationContainer>
<Drawer.Navigator
initialRouteName="Home"
drawerContentOptions={{
activeTintColor: '#e91e63',
itemStyle: {marginVertical: 30}
}}
screenOptions={{
headerShown: true,
}}>
<Drawer.Screen name="Home" component={() => <Home/>}
options={{
headerTintColor: '#fffffd',
headerTitle: () => <Text>Title</Text>,
headerLeft: () => <BackArrow/>,
}}
/>
</Drawer.Navigator>
</NavigationContainer>
);
}