Open the drawer when I click the icon react navigation version 5 - react-native

I want to open the drawer when I click the icon in the headerLeft part, I also have try to this.props.navigation.dispatch but is gives an error also navigation.dispatch gives error
The code below does not gives errors but is does not open the drawer
import { DrawerActions } from '#react-navigation/native';
import { NavigationContainer } from '#react-navigation/native';
import { createDrawerNavigator } from '#react-navigation/drawer';
import { createStackNavigator } from '#react-navigation/stack';
const Drawer = createDrawerNavigator();
const Stack = createStackNavigator();
export default class App extends Component {
createHomeStack = () =>
<Stack.Navigator>
<Stack.Screen
initialRouteName="login"
headerMode="screen"
name="main"
children={ this.createBottomTabs}
options={{
title: "Fitbit",
headerLeft: () => (
<Icon
name="menu"
size={25}
color="#D4AF37"
onPress={() => {DrawerActions.openDrawer() }}
/>
)} } />
</Stack.Navigator>
createDrawer = ({navigation}) =>
<Drawer.Navigator initialRouteName="Main" >
<Drawer.Screen name="Main" component={Main} />
<Drawer.Screen name="Contacts" component={Food} />>
</Drawer.Navigator>
render() {
return (
<NavigationContainer>
{this.createHomeStack()}
</NavigationContainer>
);
}
}

In order to achieve that you need to wrap the stack into the drawer as the documentation says.
Documentation here
I would probably use something like this:
EDIT:
Added full code
import React,{Component} from 'react'
import { NavigationContainer } from '#react-navigation/native'
import { createDrawerNavigator } from '#react-navigation/drawer'
import { createStackNavigator } from '#react-navigation/stack'
import { View } from 'react-native'
import Icon from 'react-native-vector-icons/dist/Feather'
const Drawer = createDrawerNavigator()
const Stack = createStackNavigator()
const Main = () => <View></View>
const Food = () => <View></View>
const Home = ({ navigation }) => (
<Stack.Navigator>
<Stack.Screen name="Main" component={Main} options={{
headerLeft: () => <Icon
name="menu"
size={25}
color="#D4AF37"
onPress={() => navigation.openDrawer()}
/>
}} />
</Stack.Navigator>
)
const DrawerNavigator = () => (
<Drawer.Navigator initialRouteName="Home">
<Drawer.Screen name="Home" component={Home} />
<Drawer.Screen name="Contacts" component={Food} />
</Drawer.Navigator>
)
export default props => (
<NavigationContainer>
<DrawerNavigator />
</NavigationContainer>
)

You need To import DrawerActions
import {DrawerActions } from '#react-navigation/native';
And You Can Open Using
navigation.dispatch(DrawerActions.openDrawer());

Related

Mixing both Stack navigation and tab navigation in react native

I'm trying to mix stack navigation and tab navigation i have 14 Screens:
Search,
Home,
CartTab,
SideBar,
Details,
PriceComparison,
ShopByCategory,
ShopByStore,
CategoryPage,
CategoryFilter,
Checkout,
Login,
Register,
ForgotPassword
I want to have Search, Home, CartTab, Sidebar as bottom navigation and the other pages as stack navigation, with SearchBy pages, Details, Price Comparison not displaying the bottom tab. I'm new to react native and i have been trying diffrent solutions however 1) i'm not able to remove the bottomtab from the wanted screens and 2) using navigation.navigate is returning me errores example using navigation.navigate('Category'); i get an error The action 'NAVIGATE' with payload {"name":"Category"} was not handled by any navigator. Do you have a screen named 'Category'?
This is my code :
StackNavigator.js:
import React from 'react'
import { createStackNavigator } from '#react-navigation/stack';
import { NavigationContainer } from '#react-navigation/native';
import {
CartTab,
Details,
Home,
Notification,
PriceComparison,
Search,
SplashScreen,
ShopByCategory,
ShopByStore,
CategoryPage,
Checkout,
CategoryFilter,
Login,
Register,
ForgotPassword
} from '../screens';
import { SideBar } from './../components';
export const MainStackNavigator = () => {
const Stack = createStackNavigator();
return (
<Stack.Navigator screenOptions={{headerShown: false}} initialRouteName={'Home'}>
{/*<Stack.Screen name="SplashScreen" component={SplashScreen} /> */}
<Stack.Screen name="Login" component={Login} options={{ tabBarVisible: false }} />
<Stack.Screen name="Register" component={Register} options={{ tabBarVisible: false }} />
<Stack.Screen name="Recovery" component={ForgotPassword} options={{ tabBarVisible: false }} />
<Stack.Screen name="Home" component={Home} options={{ tabBarVisible: false }} />
<Stack.Screen name="Notification" component={Notification} />
<Stack.Screen name="Comparison" component={PriceComparison} options={{ tabBarVisible: false }} />
<Stack.Screen name="ShopByCategory" component={ShopByCategory}/>
<Stack.Screen name="ShopByStore" component={ShopByStore}/>
{/*<Stack.Screen name="Category" component={CategoryPage}/>
<Stack.Screen name="CategoryFilter" component={CategoryFilter}/>*/}
</Stack.Navigator>
);
}
export const CartStackNavigator = () => {
const Stack = createStackNavigator();
return (
<Stack.Navigator screenOptions={{headerShown: false}}>
<Stack.Screen name="Cart" component={CartTab} />
<Stack.Screen name="Checkout" component={Checkout}/>
</Stack.Navigator>
);
}
export const SearchStackNavigator = () => {
const Stack = createStackNavigator();
return (
<Stack.Navigator screenOptions={{headerShown: false}}>
<Stack.Screen name="Search" component={Search} />
<Stack.Screen name="Details" component={Details}/>
</Stack.Navigator>
);
}
export const SidebarStackNavigator = () => {
const Stack = createStackNavigator();
return (
<Stack.Navigator screenOptions={{headerShown: false}}>
<Stack.Screen name="Sidebar" component={SideBar} />
<Stack.Screen name="ShopByCategory" component={ShopByCategory}/>
<Stack.Screen name="ShopByStore" component={ShopByStore}/>
<Stack.Screen name="Category" component={CategoryPage}/>
</Stack.Navigator>
);
}
TabNavigation.js:
import 'react-native-gesture-handler';
import React from 'react';
import {createBottomTabNavigator} from '#react-navigation/bottom-tabs';
import Ionicons from 'react-native-vector-icons/Ionicons';
import {COLORS} from '../constants';
import { CartStackNavigator, MainStackNavigator, SearchStackNavigator, SidebarStackNavigator }
from '../navigation/StackNavigator';
import { useStateContext } from '../context/StateContext';
const Tab = createBottomTabNavigator();
export const TabNavigation = ({navigation}) => {
return (
<Tab.Navigator
screenOptions={({ route }) => ({
headerShown: false,
tabBarIcon: ({ focused, color, size }) => {
let iconName;
if (route.name === 'Home') {
iconName = focused
? 'home'
: 'home-outline';
} else if (route.name === 'Cart') {
iconName = focused ? 'cart' : 'cart-outline';
} else if (route.name === 'Search') {
iconName = focused ? 'search' : 'search-outline';
} else if (route.name === 'SideBar') {
iconName = focused ? 'grid' : 'grid-outline';
}
// You can return any component that you like here!
return <Ionicons name={iconName} size={size} color={color} />;
},
tabBarActiveTintColor: COLORS.primary,
tabBarInactiveTintColor: 'gray',
})}
>
<Tab.Screen name="Home" component={MainStackNavigator} />
<Tab.Screen name="Search" component={SearchStackNavigator} />
<Tab.Screen name="Cart" component={CartStackNavigator} options={{ tabBarBadge: 3, tabBarBadgeStyle: { backgroundColor: COLORS.primary, marginTop: -5 } }}/>
<Tab.Screen name="SideBar" component={SidebarStackNavigator} />
</Tab.Navigator>
);
};
App.js:
import React from "react";
import { createStackNavigator } from '#react-navigation/stack';
import { NavigationContainer } from '#react-navigation/native';
import CustomDrawer from './navigation/CustomDrawer'
import {StateContext} from './context/StateContext'
import { Home, CartTab, Search, SideBar, SplashScreen, Notification, Login, Register,
ForgotPassword } from "./screens";
import { Header, TabNavigation } from "./components";
import { StripeProvider } from '#stripe/stripe-react-native';
const Stack = createStackNavigator();
const App = () => {
const [isLoading, setIsLoading] = React.useState(true);
React.useEffect(() => {
setTimeout(() => {
setIsLoading(false);
}, 3000);
}, []);
if (isLoading) {
return <SplashScreen />;
}
return (
<StateContext>
<NavigationContainer>
<TabNavigation/>
</NavigationContainer>
</StateContext>
);
}
export default App
Make two different Stacks file one is StackNavigation and other is BottomNavigation . Render your Stack Navigation and with calling the component of TabNavigation
I used the Dummy names of screens . Replace it according to your screen names
Stack navigation
import { createStackNavigator } from '#react-navigation/stack';
import { NavigationContainer } from '#react-navigation/native';
import {
CartTab,
Details,
Home,
} from '../screens';
import {TabNavigation } from '../navigation/StackNavigator';
export const StackNavigator = () => {
const Stack = createStackNavigator();
return (
<Stack.Navigator screenOptions={{headerShown: false}}
initialRouteName={'Home'}>
<Stack.Screen name="Home" component={TabNavigation}/>
<Stack.Screen name="ShopByCategory" component={ShopByCategory}/>
<Stack.Screen name="ShopByStore" component={ShopByStore}/>
<Stack.Screen name="CategoryFilter" component={CategoryFilter}/>
</Stack.Navigator>
);
}
Bottom Tab Navigation
import {createBottomTabNavigator} from '#react-navigation/bottom-tabs';
const Tab = createBottomTabNavigator();
export const TabNavigation = ({navigation}) => {
return (
<Tab.Navigator
screenOptions={({ route }) => ({
headerShown: false}
})}>
<Tab.Screen name="Example" component={Example} />
<Tab.Screen name="Search" component={Search} />
<Tab.Screen name="SideBar" component={SideBar} />
</Tab.Navigator>
);
};

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
}
})

Pass Flatlist value item to another Navigation Container React Native

I try to pass flatlist item value to other screen (main navigator), but it always return undefined. I want to achieve that when user onPress(), it will pass the value into the new screen, because I need it in the tab navigator screens. I already try to pass using using routes, but it also return undefined.
App.js
import React, {Component} from 'react';
import 'react-native-gesture-handler';
import {createStackNavigator} from '#react-navigation/stack';
import { NavigationContainer } from '#react-navigation/native';
//import another Page
import AccountSelectScreen from './screens/AccountSelectScreen';
import NewAccountScreen from './screens/NewAccountScreen';
import MainNavigator from './screens/MainNavigator';
import HomeScreen from './screens/HomeScreen';
import VaccineScreen from './screens/VaccineScreen';
import NotificationScreen from './screens/NotificationScreen';
import UserScreen from './screens/UserScreen';
import SplashScreen from './screens/SplashScreen';
import SignUpAccScreen from './screens/SignUpAccScreen';
import RegisterScreen from './screens/RegisterScreen';
import ScanQR from './screens/ScanQR';
const styles = require('./styles/styles');
const Stack = createStackNavigator();
const Auth = (route) => {
// Stack Navigator for Login and Sign up Screen
return (
<Stack.Navigator initialRouteName="SignUpAcc">
<Stack.Screen
name="SignUpAcc"
component={SignUpAccScreen}
options={{headerShown: false}}
/>
<Stack.Screen
name="AccountSelectScreen"
component={AccountSelectScreen}
options={{headerShown: false}}
/>
<Stack.Screen
name="NewAccountScreen"
component={NewAccountScreen}
options={{headerShown: false}}
/>
<Stack.Screen
name="RegisterScreen"
component={RegisterScreen}
options={{headerShown: false}}
/>
</Stack.Navigator>
);
};
const App = () => {
return (
<NavigationContainer>
<Stack.Navigator initialRouteName="SplashScreen">
<Stack.Screen
name="SplashScreen"
component={SplashScreen}
// Hiding header for Splash Screen
options={{headerShown: false}}
/>
{/* Auth Navigator: Include Login and Signup */}
<Stack.Screen
name="Auth"
component={Auth}
options={{headerShown: false}}
/>
{/* Navigation Drawer as a landing page */}
<Stack.Screen
name="MainNavigator"
component={MainNavigator}
// Hiding header for Navigation Menu
options={{headerShown: false}}
/>
<Stack.Screen
name="BarcodeScan"
component={ScanQR}
options={{headerShown: false}}
/>
</Stack.Navigator>
</NavigationContainer>
);
};
export default App;
renderItem flatlist
const renderItem = ({ item }) => (
<View style={{marginBottom: 20}}>
<Pressable
style={styles.baby_box}
title={item.nameVal}
>
<Text>{item.nameVal}</Text>
</Pressable>
<Pressable
style={styles.btnDelete}
value={item.nameVal}
onPress={() => {
// selectChild(text)
navigation.navigate('MainNavigator',{
nameChild: item.nameVal
});
}}
>
<Text style={styles.btnText}>Pilih</Text>
</Pressable>
</View>
);
const MainNavigator = (route,navigation) => {
const {nameChild} = route.params;
}
export default MainNavigator;
From this given code i think you are destructuring props in the wrong way thats why its undefined.
const MainNavigator = (route,navigation) => {
const {nameChild} = route.params;
}
export default MainNavigator;
Try this.
const MainNavigator = (props) => {
const {nameChild} = props.route.params;
}
export default MainNavigator;
You have to add curly braces so it takes parameters with in the object
Like this:({route,navigation})
const MainNavigator = ({route,navigation}) => {
const {nameChild} = route.params;
}
export default MainNavigator;

Combine Drawer.Navigator and Stack.Navigator without creating separate navigation bars

I would like to have stack and drawer navigators use the same navigation bar. However, both are creating their own navigation bars refer to the below image making the app look messy. How can I achieve that?
Below is my code:
import * as React from "react";
import { createStackNavigator } from "#react-navigation/stack";
import { createDrawerNavigator } from "#react-navigation/drawer";
import Home from "../screens/Home";
import Contact from "../screens/Contact";
import About from "../screens/About";
const Stack = createStackNavigator();
const Drawer = createDrawerNavigator();
const HomeNavigation = (props) => {
return (
<Stack.Navigator initialRouteName='Home'
screenOptions={{
headerTitleAlign:'center',
//headerShown: false
}}
>
<Stack.Screen name='Home' component={Home} />
<Stack.Screen name='Contact' component={Contact} />
<Stack.Screen name='About' component={About} />
</Stack.Navigator>
);
};
const MenuNavigation = (props) => {
return (
<Stack.Navigator initialRouteName='Home'
screenOptions={{
headerTitleAlign:'center',
//headerShown: false
}}>
<Stack.Screen name='Menu' component={About} />
</Stack.Navigator>
);
};
const DrawerNavigation = () => {
return (
<Drawer.Navigator>
<Drawer.Screen name='HomeNavigation' component={HomeNavigation} />
<Drawer.Screen name='MenuNavigation' component={MenuNavigation} />
</Drawer.Navigator>
);
};
export default DrawerNavigation;

Is there a good way to set headerRight to pass onPress event in React Native

my friends, hope you doing well, I need some help with my React Native project.
I have the following code and struggling with the navigation for the "NewPost" screen.
I want to create a button in the header and handle press on it but can not figure out how to do it. Thanks for your precious help:
import React from 'react';
import 'react-native-gesture-handler';
import { TouchableOpacity } from 'react-native'
import { NavigationContainer } from '#react-navigation/native';
import { createStackNavigator } from '#react-navigation/stack';
import { Provider } from './src/context/BlogContext';
import IndexScreen from './src/screens/IndexScreen';
import CreatePost from './src/screens/CreatePost';
import ShowScreen from './src/screens/ShowScreen';
import { AntDesign } from '#expo/vector-icons'
const Stack = createStackNavigator()
const App = ({navigation}) => {
return (
<NavigationContainer>
<Stack.Navigator initialRouteName='Index'>
<Stack.Screen name='Index'
component={IndexScreen}
options={{
title: 'Blogs',
headerRight: () => (
<TouchableOpacity onPress={() => navigation.navigate('NewPost')}>
<AntDesign name="plus" size={24} color="black" />
</TouchableOpacity>
)
}} />
<Stack.Screen name='ShowScreen' component={ShowScreen} options={{ title: 'Post Details' }} />
<Stack.Screen name='NewPost' component={CreatePost} options={{ title: 'Create a Post' }} />
</Stack.Navigator>
</NavigationContainer>
);
}
export default () => {
return (
<Provider>
<App />
</Provider>
)
}
First thing you cannot access navigation outside of the NavigationContainer so remove navigation from your App declaration :
const App = ({}) => { // remove navigation object from here
Now, to do user redirection on headerRight press, you can actually access naviagation on your headerRight and navigation user as below :
headerRight: ({navigation}) => (
<TouchableOpacity onPress={() => navigation.navigate('NewPost')}>
<AntDesign name="plus" size={24} color="black" />
</TouchableOpacity>
)
We can use useNavigation hook to implement the navigation In the navigator component.
For Example:
import React from 'react';
import 'react-native-gesture-handler';
import { TouchableOpacity } from 'react-native'
import { NavigationContainer, useNavigation } from '#react-navigation/native';
import { createStackNavigator } from '#react-navigation/stack';
import { Provider } from './src/context/BlogContext';
import IndexScreen from './src/screens/IndexScreen';
import CreatePost from './src/screens/CreatePost';
import ShowScreen from './src/screens/ShowScreen';
import { AntDesign } from '#expo/vector-icons'
const Stack = createStackNavigator()
const App = props => {
const navigation = useNavigation();
return (
<NavigationContainer>
<Stack.Navigator initialRouteName='Index'>
<Stack.Screen name='Index'
component={IndexScreen}
options={{
title: 'Blogs',
headerRight: () => (
<TouchableOpacity onPress={() => navigation.navigate('NewPost')}>
<AntDesign name="plus" size={24} color="black" />
</TouchableOpacity>
)
}} />
<Stack.Screen name='ShowScreen' component={ShowScreen} options={{ title: 'Post Details' }} />
<Stack.Screen name='NewPost' component={CreatePost} options={{ title: 'Create a Post' }} />
</Stack.Navigator>
</NavigationContainer>
);
}
export default () => {
return (
<Provider>
<App />
</Provider>
)
}
Here is the solution I got for my question:
options={({navigation}) => ({
title: 'Blogs',
headerRight: () => (
<TouchableOpacity onPress={() => navigation.navigate('NewPost')}>
import React from 'react';
import 'react-native-gesture-handler';
import { TouchableOpacity } from 'react-native'
import { NavigationContainer } from '#react-navigation/native';
import { createStackNavigator } from '#react-navigation/stack';
import { Provider } from './src/context/BlogContext';
import IndexScreen from './src/screens/IndexScreen';
import CreatePost from './src/screens/CreatePost';
import ShowScreen from './src/screens/ShowScreen';
import { AntDesign } from '#expo/vector-icons'
const Stack = createStackNavigator()
const App = () => {
return (
<NavigationContainer>
<Stack.Navigator initialRouteName='Index'>
<Stack.Screen name='Index'
component={IndexScreen}
options={({navigation}) => ({
title: 'Blogs',
headerRight: () => (
<TouchableOpacity onPress={() => navigation.navigate('NewPost')}>
<AntDesign name="plus" size={24} color="black" />
</TouchableOpacity>
)
})} />
<Stack.Screen name='ShowScreen' component={ShowScreen} options={{ title: 'Post Details' }} />
<Stack.Screen name='NewPost' component={CreatePost} options={{ title: 'Create a Post' }} />
</Stack.Navigator>
</NavigationContainer>
);
}
export default () => {
return (
<Provider>
<App />
</Provider>
)
}