Undefined is not an object 'navigation.navigate' React Native Navigation 5 (NEW) - react-native

I am doing doing navigation with new react native navigation all I want is when button is pressed it navigate to next screen, I have followed new documentation but the problem is I am doing with classes and in the documentation all the work is done with functions in App.js, I tried to modify my code accordingly but couldn't do with classes as onPress button it does not navigate instead gives me error.
This is my app.js:
import * as React from 'react';
import { Button, View, Text } from 'react-native';
import { NavigationContainer,useNavigation } from '#react-navigation/native';
import { createStackNavigator } from '#react-navigation/stack';
import Nav from './screens/Nav';
import Home from './screens/Home';
import Login from './screens/Login';
const Stack = createStackNavigator();
export default class App extends React.Component {
render(){
return (
<NavigationContainer>
<Stack.Navigator headerMode='none' initialRouteName="Nav">
<Stack.Screen name="Splash" component={Nav} />
<Stack.Screen name="Home" component={Home} />
<Stack.Screen name="Login" component={Login} />
</Stack.Navigator>
</NavigationContainer>
);
}
}
That is my Home.js from where when it clicks Login button it moves to next screen which is Login.js:
import React, { Component } from 'react';
import {StyleSheet, Text, View, TouchableHighlight,Image,BackHandler} from 'react-native';
import Login from './Login';
export default class Home extends Component {
render() {
const { navigation } = this.props;
return (
<View style={styles.container}>
<TouchableHighlight style={styles.buttonContainer} onPress={() => navigation.navigate('Login')}>
<Text style={styles.loginText}>Login</Text>
</TouchableHighlight>
</View>
);
}
}
That is my Login.js Screen:
import React, { Component } from 'react';
import {StyleSheet, Text, View,TextInput,TouchableHighlight, Image} from 'react-native';
export default class Login extends Component {
constructor(props) {
super(props);
this.state = {
email : '',
password: '',
}
}
render() {
return (
<View style={styles.container}>
<Image source={require('../assets/logo.png')}
style={{ width: 250, height: 250, marginHorizontal: 20 }}
resizeMode="contain"/>
<Text style = {styles.text}>UniQmove Training </Text>
<View style={styles.inputContainer}>
<Image style={styles.inputIcon} source={{uri: 'https://img.icons8.com/ultraviolet/40/000000/email.png'}}/>
<TextInput style={styles.inputs}
placeholder="Email"
keyboardType="email-address"
underlineColorAndroid='transparent'
onChangeText={(email) => this.setState({email})}/>
</View>
<View style={styles.inputContainer}>
<Image style={styles.inputIcon} source={{uri: 'https://img.icons8.com/ultraviolet/40/000000/password.png'}}/>
<TextInput style={styles.inputs}
placeholder="Password"
secureTextEntry={true}
underlineColorAndroid='transparent'
onChangeText={(password) => this.setState({password})}/>
</View>
<TouchableHighlight style={[styles.buttonContainer, styles.loginButton]} onPress={() => {this.loginRoles();this.handleLogin();}}>
<Text style={styles.loginText}>Login</Text>
</TouchableHighlight>
</View>
);
}
}
The problem is when I import Login.js in Home it is not using it in navigation.navigate('Login')
My package.jason:
{
"name": "UniQmoves",
"version": "0.0.1",
"private": true,
"scripts": {
"android": "react-native run-android",
"ios": "react-native run-ios",
"start": "react-native start",
"test": "jest",
"lint": "eslint ."
},
"dependencies": {
"#react-native-community/masked-view": "^0.1.7",
"#react-navigation/native": "^5.0.9",
"#react-navigation/stack": "^5.1.1",
"react": "16.9.0",
"react-native": "0.61.5",
"react-native-gesture-handler": "^1.6.0",
"react-native-reanimated": "^1.7.0",
"react-native-safe-area-context": "^0.7.3",
"react-native-screens": "^2.3.0"
},
"devDependencies": {
"#babel/core": "7.8.7",
"#babel/runtime": "7.8.7",
"#react-native-community/eslint-config": "0.0.5",
"babel-jest": "24.9.0",
"eslint": "6.8.0",
"jest": "24.9.0",
"metro-react-native-babel-preset": "0.56.4",
"react-test-renderer": "16.9.0"
},
"jest": {
"preset": "react-native"
}
}

there is a little change in code and your code will work fine
in App Class initialRouteName and screen name should same change Splash to Nav
<Stack.Navigator headerMode='none' initialRouteName="Nav">
<Stack.Screen name="Splash" component={Nav} />
in Home class update after use this line
import React, { Component } from 'react';
import {StyleSheet, Text, View, TouchableHighlight,Image,BackHandler} from 'react-native';
import Login from './Login';
export default class Home extends Component {
render() {
return (
<View style={styles.container}>
//<TouchableHighlight style={styles.buttonContainer} onPress={() => navigation.navigate('Login')}>
use this
<TouchableHighlight style={styles.buttonContainer} onPress={() => this.props.navigation.navigate('Login')}>
<Text style={styles.loginText}>Login</Text>
</TouchableHighlight>
</View>
);
}
}

Related

react native material ui date time picker error: Invariant Violation

I want to incorporate the MaterialUI date-time-pickers into my MERN project and to test the waters I just want to render the JS example (not typescript) from the "Getting-Started" section of the MaterialUI website: https://mui.com/x/react-date-pickers/getting-started/. I have an App.js file where my routing, screens and providers are located. I want to render the example on my CountdownScreen.js file. I assumed that I would need to wrap my screens in the LocalizationProvider component in my App.js file as opposed to wrapping the pickers like how the example shows but I tried both ways and it didn't seem to help. I'm getting the following error:
Invariant Violation: View config getter callback for component style must be a function (received undefined). Make sure to start component names with a capital letter.
MaterialUI has changed their syntax
(https://mui.com/material-ui/guides/pickers-migration/)
so its hard to find new tutorials that don't use the deprecated code. I don't get what I'm doing wrong. I may have downloaded too many conflicting dependencies but I'm not sure which one is the culprit. Thank you in advance. Also, if I didn't want to use MaterialUI are there any other decent date/time pickers out there?
Below is my CountdownScreen.js code:
import React from "react";
import { View, StyleSheet } from "react-native";
import dayjs from "dayjs";
import Stack from "#mui/material/Stack";
import TextField from "#mui/material/TextField";
import { LocalizationProvider } from "#mui/x-date-pickers/LocalizationProvider";
import { AdapterDayjs } from "#mui/x-date-pickers/AdapterDayjs";
import { TimePicker } from "#mui/x-date-pickers/TimePicker";
import { DateTimePicker } from "#mui/x-date-pickers/DateTimePicker";
import { DesktopDatePicker } from "#mui/x-date-pickers/DesktopDatePicker";
import { MobileDatePicker } from "#mui/x-date-pickers/MobileDatePicker";
const CountdownScreen = () => {
const [value, setValue] = React.useState(dayjs("2014-08-18T21:11:54"));
const handleChange = (newValue) => {
setValue(newValue);
};
return (
<View>
<LocalizationProvider dateAdapter={AdapterDayjs}>
<Stack spacing={3}>
<DesktopDatePicker
label="Date desktop"
inputFormat="MM/DD/YYYY"
value={value}
onChange={handleChange}
renderInput={(params) => <TextField {...params} />}
/>
<MobileDatePicker
label="Date mobile"
inputFormat="MM/DD/YYYY"
value={value}
onChange={handleChange}
renderInput={(params) => <TextField {...params} />}
/>
<TimePicker
label="Time"
value={value}
onChange={handleChange}
renderInput={(params) => <TextField {...params} />}
/>
<DateTimePicker
label="Date and Time picker"
value={value}
onChange={handleChange}
renderInput={(params) => <TextField {...params} />}
/>
</Stack>
</LocalizationProvider>
</View>
);
};
CountdownScreen.navigationOptions = { title: "Countdown" };
const styles = StyleSheet.create({
countdownScreenStyle: {
flex: 1,
alignItems: "center",
justifyContent: "center",
backgroundColor: "rgba(232, 180, 68, 1.0)",
height: "100%",
width: "100%",
flex: 1,
},
});
export default CountdownScreen;
Below is my App.js:
import * as React from "react";
import { NavigationContainer, useIsFocused } from "#react-navigation/native";
import { createStackNavigator } from "#react-navigation/stack";
import { createNativeStackNavigator } from "#react-navigation/native-stack";
import { createBottomTabNavigator } from "#react-navigation/bottom-tabs";
import { SafeAreaProvider, SafeAreaView } from "react-native-safe-area-context";
//https://mui.com/material-ui/guides/pickers-migration/
import HomeScreen from "./src/screens/HomeScreen";
import CountdownScreen from "./src/screens/CountdownScreen";
import WeatherScreen from "./src/screens/WeatherScreen";
import MusicScreen from "./src/screens/MusicScreen";
import SettingsScreen from "./src/screens/SettingsScreen";
import { Ionicons } from "#expo/vector-icons";
const Tab = createBottomTabNavigator();
export default function App() {
return (
<SafeAreaProvider>
<NavigationContainer>
<Tab.Navigator
screenOptions={({ route }) => ({
tabBarIcon: ({ focused, color, size }) => {
let iconName;
if (route.name === "Home") {
iconName = focused ? "home" : "home-outline";
} else if (route.name === "Countdown") {
iconName = focused ? "timer" : "timer-outline";
} else if (route.name === "Weather") {
iconName = focused ? "partly-sunny" : "partly-sunny-outline";
} else if (route.name === "Music") {
iconName = focused
? "musical-notes"
: "musical-notes-outline";
} else if (route.name === "Settings") {
iconName = focused ? "settings" : "settings-outline";
}
return <Ionicons name={iconName} size={size} color={color} />;
},
tabBarActiveTintColor: "tomato",
tabBarInactiveTintColor: "gray",
})}
>
<Tab.Screen name="Home" component={HomeScreen} />
<Tab.Screen name="Countdown" component={CountdownScreen} />
<Tab.Screen name="Weather" component={WeatherScreen} />
<Tab.Screen name="Music" component={MusicScreen} />
<Tab.Screen name="Settings" component={SettingsScreen} />
</Tab.Navigator>
</NavigationContainer>
</SafeAreaProvider>
);
}
Below is my package.json file:
{
"name": "countdown-hound",
"version": "1.0.0",
"main": "node_modules/expo/AppEntry.js",
"scripts": {
"start": "expo start",
"android": "expo start --android",
"ios": "expo start --ios",
"web": "expo start --web"
},
"dependencies": {
"#date-io/date-fns": "^1.3.13",
"#emotion/react": "^11.10.4",
"#emotion/styled": "^11.10.4",
"#material-ui/core": "^5.0.0-beta.5",
"#material-ui/lab": "^5.0.0-alpha.44",
"#mui/icons-material": "^5.10.6",
"#mui/lab": "^5.0.0-alpha.100",
"#mui/material": "^5.10.6",
"#mui/x-date-pickers": "^5.0.3",
"#react-native-community/datetimepicker": "^6.3.2",
"#react-navigation/bottom-tabs": "^6.3.3",
"#react-navigation/drawer": "^6.4.4",
"#react-navigation/native": "^6.0.12",
"#react-navigation/native-stack": "^6.8.0",
"#react-navigation/stack": "^6.2.3",
"#rneui/base": "^4.0.0-rc.6",
"#rneui/themed": "^4.0.0-rc.6",
"axios": "^0.27.2",
"date-fns": "^2.29.3",
"dayjs": "^1.11.5",
"expo": "~46.0.9",
"expo-location": "~14.3.0",
"expo-secure-store": "^11.3.0",
"expo-status-bar": "~1.4.0",
"material-ui": "^0.20.2",
"moment": "^2.29.4",
"react": "18.0.0",
"react-css-transition-replace": "^4.0.5",
"react-dom": "^18.2.0",
"react-native": "0.69.5",
"react-native-gesture-handler": "~2.5.0",
"react-native-localize": "^2.2.3",
"react-native-maps": "^1.3.1",
"react-native-reanimated": "^2.9.1",
"react-native-safe-area-context": "^4.3.1",
"react-native-screens": "~3.15.0",
"react-native-segmented-control": "^1.1.0",
"react-native-windows": "^0.69.6",
"react-navigation": "^4.4.4",
"react-time-picker-input": "^2.0.10"
},
"devDependencies": {
"#babel/core": "^7.12.9"
},
"private": true
}

React Native Unexpected token '{'. import call expects exactly one argument

Hello guys I'm new to React Native and I was going along with a tutorial on YouTube. There I imported heroicons as this is what I needed to do. Everything works fine until I import the actual Icons like this:
import { UserIcon, ChevronDownIcon, SearchIcon, AdjustmentsIcon, } from "react-native-heroicons/outline"
Then the error: Unexpected token '{'. import call expects exactly one argument. no stack comes up. Is there anyone who knows how I can solve this problem as everything I found so far didn't work.
My dependencies:
"dependencies": {
"#react-navigation/native": "^6.0.11",
"#react-navigation/native-stack": "^6.7.0",
"#react-navigation/stack": "^6.2.2",
"expo": "~46.0.6",
"expo-status-bar": "~1.4.0",
"react": "18.0.0",
"react-native": "0.69.4",
"react-native-heroicons": "^2.2.0",
"react-native-safe-area-context": "4.3.1",
"react-native-screens": "~3.15.0",
"react-native-svg": "12.3.0",
"react-navigation-stack": "^2.10.4",
"tailwindcss-react-native": "^1.7.10"
},
HomeScreen:
import { View, Text, SafeAreaView, StyleSheet, Platform, StatusBar, Image } from 'react-native';
import React, { useLayoutEffect } from 'react';
import { useNavigation } from '#react-navigation/native';
import { UserIcon, ChevronDownIcon, SearchIcon, AdjustmentsIcon, } from "react-native-heroicons/outline"
const HomeScreen = () => {
const navigation = useNavigation();
useLayoutEffect(() => {
navigation.setOptions({
headerShown: false,
});
}, [])
return (
<SafeAreaView style={styles.AndroidSafeArea}>
<Text className='text-red-500'>
{/* Header */}
<View className="flex-row pb-3 items-center mx-4 space-x-2">
<Image
source={{
uri: 'http://links.papareact.com/wru'
}}
className='h-7 w-7 bg-gray-300 p-4 rounded-full'
/>
<View>
<Text className="font-bold text-gray-400 text-xs">
Deliver Now!
</Text>
<Text className="font-bold text-xl">
Current Location
<ChevronDownIcon size={20} color="#00CCBB"/>
</Text>
</View>
</View>
</Text>
</SafeAreaView>
)
}
const styles = StyleSheet.create({
AndroidSafeArea: {
flex: 1,
backgroundColor: "white",
paddingTop: Platform.OS === "android" ? StatusBar.currentHeight : 0
}
})
export default HomeScreen
Thank you for your help :)
I run into same issue if you run your app using expo start or npx expo start you should see that they are telling you where is the issue.
My issue was that react-native-svg version was hire then what expo was expected i just run expo doctor --fix-dependencies and it should fix the version of react-native-svg installed

How to create multiple screens on React Native?

import React from 'react';
import {TextInput, StyleSheet, Text, View } from 'react-native';
import {Button} from 'react-native-elements';
import { Navigation } from 'react-native-navigation';
import Signup from "./Signup";
export default function App() {
return (
<View style={styles.container}>
<Text style={{marginTop: 0}}>Junior Facebook</Text>
<TextInput placeholder="Email" style={{width: 80, height: 30}}/>
<TextInput placeholder="Password" style={{width:80, height: 30}}/>
<Button title="Log In">Log In</Button>
<Button title="Sign Up">Sign Up</Button>
</View>
);
}
const styles = StyleSheet.create({
container: {
flex: 1,
backgroundColor: '#fff',
alignItems: 'center',
justifyContent: 'center',
},
});
I am trying to make a new screen called "Signup". How can I?
Thank you
I heard I can use react navigation so I googled it but it does not work either.
Please help me out here,
You need to install Stack Navigator module to do this.
Create Stack navigator with screen like below code. (here i have used signin Page and signup Page, Please change to your pages and also import).
import this stack navigator into app.js file and wraps it with navigation container;
Link to official docs
Stack Navigator
import React from "react";
import { createStackNavigator } from "#react-navigation/stack";
import SignIn from "../screens/auth/SignIn";
import SignUp from "../screens/auth/SignUp";
const AuthStack = () => {
const AuthStack = createStackNavigator();
return (
<AuthStack.Navigator>
<AuthStack.Screen
name="Sign In"
component={SignIn}
options={{
headerTitle: "",
headerTransparent: true
}}
/>
<AuthStack.Screen
name="Sign Up"
component={SignUp}
options={{
headerTitle: "",
headerTransparent: true
}}
/>
</AuthStack.Navigator>
);
};
export default AuthStack;
App.js
import other stuff;
import { NavigationContainer } from "#react-navigation/native";
import AuthStackScreen from "./routes/AuthStack";
export default App = () => {
return (
<SafeAreaView>
<NavigationContainer>
<AuthStackScreen />
</NavigationContainer>
</SafeAreaView>
);
SignIn.js
const SignIn = ({navigation}) => {
return (
<button onClick={navigation.navigate("Sign Up")}>Click to Navigate</button>
);
}
Package.json
"#react-native-community/masked-view": "0.1.5",
"#react-navigation/native": "^5.0.5",
"#react-navigation/stack": "^5.0.5",
"react-native-safe-area-context": "0.6.0",
"react-native-screens": "2.0.0-alpha.12",
"react-native-web": "^0.11.7",
"react-native-webview": "7.4.3"

How to decrease launch time of react native app

I am developing news app using react native, and my problem is the launch or startup time of app is long(before the home screen shows), I would appreciate any advice to improve the speed.It takes around 4 seconds to load initially and 2 seconds for the js. I have 36 articles to show on home screen and the json response is big and maybe it is the reason of the problem.
My package.json looks like this :
{
"name": "tageblattapp",
"version": "0.0.1",
"private": true,
"scripts": {
"android": "react-native run-android",
"ios": "react-native run-ios",
"start": "react-native start",
"test": "jest",
"lint": "eslint ."
},
"dependencies": {
"#react-native-community/masked-view": "^0.1.7",
"moment": "^2.24.0",
"native-base": "^2.13.12",
"react": "16.11.0",
"react-native": "0.62.0",
"react-native-gesture-handler": "^1.6.1",
"react-native-optimized-flatlist": "^1.0.4",
"react-native-reanimated": "^1.7.1",
"react-native-render-html": "^4.2.0",
"react-native-safe-area-context": "^0.7.3",
"react-native-safe-area-view": "^1.0.0",
"react-native-screens": "^2.7.0",
"react-native-vector-icons": "^6.6.0",
"react-native-webview": "^9.3.0",
"react-navigation": "^4.3.5",
"react-navigation-drawer": "^2.4.12",
"react-navigation-stack": "^2.3.9"
},
"devDependencies": {
"#babel/core": "7.9.0",
"#babel/runtime": "7.9.2",
"#react-native-community/eslint-config": "0.0.5",
"babel-jest": "24.9.0",
"eslint": "6.8.0",
"jest": "24.9.0",
"metro-react-native-babel-preset": "0.58.0",
"react-test-renderer": "16.11.0"
},
"jest": {
"preset": "react-native"
},
"rnpm": {
"assets": [
"../assets/fonts/"
]
}
}
My imports are:
import React,{PureComponent} from 'react';
import {AsyncStorage, Linking ,Share, View ,Image,ActivityIndicator ,StyleSheet, TouchableOpacity,Dimensions,ScrollView,SafeAreaView, TextInput ,FlatList} from 'react-native';
import Icon from 'react-native-vector-icons/FontAwesome';
import { createAppContainer } from 'react-navigation';
import {Container, Header, Left, Body, Right, Button, Title,Text,Content, List, ListItem,Thumbnail} from 'native-base';
import { createStackNavigator } from 'react-navigation-stack';
import { createDrawerNavigator } from 'react-navigation-drawer';
import { IMAGE } from '../constants/image';
import { getMenusideGategory} from '../services/news';
import HTML from 'react-native-render-html';
import Time from '../components/time';
import moment from 'moment';
import FeedDetail from './FeedDetail';
import ArticleLink from './ArticleLink';
import Comments from './Comments';
import AddComments from './AddComments';
The funcyion that gets articles:
export async function getArticles(){
try {
let articles = await fetch(`${articles_url}`,{
headers:{
'X-API-KEY':_api_key
}
});
let result = await articles.json();
return result.articles;
} catch (error) {
throw error
}
}
The home.js that display the articles is :
export class HomeScreen extends PureComponent {
constructor(props) {
super(props);
this._handleItemDataOnPress = this._handleItemDataOnPress.bind(this)
this.state = {
isLoading: true,
data: null,
isError: false,
setModalVisible: false,
modalArticleData: {}
}
}
_handleItemDataOnPress(articleData) {
this.setState({
setModalVisible: true,
modalArticleData: articleData
})
}
componentDidMount() {
getArticles().then(data => {
this.setState({
isLoading: false,
data: data
})
}, error => {
Alert.alert("Error", "Something happend, please try again")
})
}
render() {
let view = this.state.isLoading ? (
<View style={{ flex: 1, alignItems: 'center', justifyContent: 'center' }}>
<ActivityIndicator animating={this.state.isLoading} color="#00f0ff" />
<Text style={{ marginTop: 8 }} children="Please wait..." />
</View>
) : (
<FlatList
dataArray={this.state.data}
renderRow={(item) => {
return (
<ListItem>
<ListDataItem onPress={this._handleItemDataOnPress} data={item} />
</ListItem>
)
}} />
)
return (
<Container>
<Header>
<Body>
<Title children="RN NewsApp" />
</Body>
</Header>
<Content
contentContainerStyle={{ flex: 1, backgroundColor: '#fff' }}
padder={false}>
{view}
</Content>
</Container>
)
}
}
The class ListDataItem that shows single data item inside the list renderRow:
export default class ListDataItem extends PureComponent{
constructor(props){
super(props);
this.data = props.data;
this._handlePress = this._handlePress.bind(this)
}
_handlePress(){
const {url, title} = this.data
this.props.onPress({url,title})
}
render(){
return(
<TouchableOpacity onPress={this._handlePress} style={{flexDirection:'row'}} activeOpacity={0.5}>
<Thumbnail style={{ backgroundColor: '#eee', alignSelf: 'center' }} square large source={{ cache:'force-cache', uri: this.data.urlToImage != null ? this.data.urlToImage : null }} />
<Body>
<Text style={{fontSize: 16 }} numberOfLines={2}>{this.data.title}</Text>
<Text note numberOfLines={3}>{this.data.description}</Text>
<View style={{ flex: 1, flexDirection: 'row', marginTop: 8, marginLeft: 8 }}>
<Text note>{this.data.source.name}</Text>
<TimeAgo date={this.data.publishedAt} />
</View>
</Body>
</TouchableOpacity>
)
}
}
I tried also to put the header inside the flatlist using LisHeaderComponent, but there was no difference.
Decrease your start up time and RAM memory consumption by an application via splitting JS bundle by components and navigation routes.
https://www.npmjs.com/package/react-native-bundle-splitter
Just by creating a release Apk/Build
In a release Apk, App loads in just half a second which means the Splash screen or Launch screen shows up for half a second only.

React navigation drawer V5

I'm using react-navigation version 5.
I have tab navigation and drawer navigation together.
I'm trying to add an icon in my header to open/close drawer:
here is my custom right header for toggling the drawer:
const HeaderRight = ({ navigation }) => {
return (
<View style={{flexDirection: 'row'}}>
<TouchableOpacity
onPress={ () =>{ navigation.toggleDrawer()}}> //here is the problem
<Image source={require('./assets/images/icons/drawer.png')}/>
</TouchableOpacity>
</View>
);}
this is my tab navigator:
const Tab = createBottomTabNavigator();
function AppTab() {
return (
<Tab.Navigator>
<Tab.Screen name="Category" component={Category} />
<Tab.Screen name="Home" component={Home}/>
</Tab.Navigator>
);}
drawer navigator:
const Drawer = createDrawerNavigator();
function App() {
return (
<Drawer.Navigator>
<Drawer.Screen name="AppTab" component={AppTab} />
<Drawer.Screen name="Notifications" component={NotificationsScreen} />
</Drawer.Navigator>
);}
and my stack navigator to theme mix all:
const Stack = createStackNavigator();
export default function MyStack() {
return (
<NavigationContainer>
<Stack.Navigator
headerMode="screen"
screenOptions={{
headerRight: ({ navigation }) => (<HeaderRight navigation={navigation} />
),}} >
<Stack.Screen name="Settings" component={Settings} />
</Stack.Navigator>
</NavigationContainer>
);
}
when I press the right header icon
what I'm missing here?
the documents weren't really helpful
note:I have also try using dispatch but it didn't work:
navigation.dispatch(DrawerActions.toggleDrawer())
package.json:
{
"name": "test",
"version": "0.0.1",
"private": true,
"scripts": {
"android": "react-native run-android",
"ios": "react-native run-ios",
"start": "react-native start",
"test": "jest",
"lint": "eslint ."
},
"dependencies": {
"#react-native-community/async-storage": "^1.8.0",
"#react-native-community/masked-view": "^0.1.6",
"#react-navigation/bottom-tabs": "^5.0.5",
"#react-navigation/drawer": "^5.0.5",
"#react-navigation/native": "^5.0.5",
"#react-navigation/stack": "^5.0.5",
"moment": "^2.24.0",
"randomcolor": "^0.5.4",
"react": "16.9.0",
"react-native": "0.61.5",
"react-native-base64": "0.0.2",
"react-native-gesture-handler": "^1.6.0",
"react-native-image-slider": "^2.0.3",
"react-native-reanimated": "^1.7.0",
"react-native-safe-area-context": "^0.7.3",
"react-native-screens": "^2.0.0-beta.4",
"react-native-woocommerce-api": "^1.0.12"
},
"devDependencies": {
"#babel/core": "^7.6.2",
"#babel/runtime": "^7.6.2",
"#react-native-community/eslint-config": "^0.0.5",
"babel-jest": "^24.9.0",
"eslint": "^6.5.1",
"jest": "^24.9.0",
"metro-react-native-babel-preset": "^0.56.0",
"react-test-renderer": "16.9.0"
},
"jest": {
"preset": "react-native"
}
}
i have created an simple example deppending upon what i understood, i hope it helps,
u can use options props of Stack.Screen to render custom right or left button and in button component use useNavigation hook to get navigation prop and toggle the drawer user navigation.dispatch(DrawerActions.toggleDrawer())
import React, {useEffect} from 'react';
import {View, Text, StyleSheet, Image} from 'react-native';
import {NavigationContainer, useNavigation, DrawerActions} from '#react-navigation/native';
import {createDrawerNavigator} from '#react-navigation/drawer';
import {createBottomTabNavigator} from '#react-navigation/bottom-tabs';
import {createStackNavigator, HeaderBackButton, Header} from '#react-navigation/stack';
import Home from './src/home';
import {TouchableOpacity} from 'react-native-gesture-handler';
const Stack = createStackNavigator();
const Drawer = createDrawerNavigator();
const Tab = createBottomTabNavigator();
const TabComponent = () => {
return (
<Tab.Navigator>
<Tab.Screen component={Home} name="Home1" />
<Tab.Screen component={Home} name="Home2" />
{/*
* Rest Screens
*/}
</Tab.Navigator>
);
};
const DrawerComponent = () => {
return (
<Drawer.Navigator>
<Drawer.Screen component={TabComponent} name="Main" />
{/*
* Rest Screens
*/}
</Drawer.Navigator>
);
};
const HeaderLeft = () => {
const navigation = useNavigation();
return (
<View style={{flexDirection: 'row'}}>
<TouchableOpacity
onPress={() => {
navigation.dispatch(DrawerActions.openDrawer());
}}>
<Text>Open</Text>
{/* <Image source={require('./assets/images/icons/drawer.png')} /> */}
</TouchableOpacity>
</View>
);
};
export default () => {
return (
<NavigationContainer>
<Stack.Navigator>
<Stack.Screen
options={{
headerLeft: ({}) => <HeaderLeft />
}}
component={DrawerComponent}
name="Drawer"
/>
{/*
* Rest Screens
*/}
</Stack.Navigator>
</NavigationContainer>
);
};
Instead of toggleDrawer() use openDrawer()
STEPS
import { DrawerActions } from '#react-navigation/native';
navigation.dispatch(DrawerActions.openDrawer());
If the above function not working try this:
this.props.navigation.openDrawer()
UPDATE CODE
const HeaderRight = ({ navigation }) => {
return (
<View style={{ flexDirection: "row" }}>
<TouchableOpacity
onPress={() => {
navigation.dispatch(DrawerActions.openDrawer());
}}
>
<Image source={require("./assets/images/icons/drawer.png")} />
</TouchableOpacity>
</View>
);
};
Make sure you have imported the package before using
if this.props.navigation.openDrawer() isnt work, you may try useNavigation.
import { useNavigation } from '#react-navigation/native';
in your header function() add
const navigation = useNavigation();
and add navigation.openDrawer() to onPress
this is worck for me !
headerRight: () => (
<HeaderButtons HeaderButtonComponent={HeaderButton}> // this is a cutom button
<Item
title="Favorite"
iconName="ios-menu"
onPress={() => {navigation.navigation.toggleDrawer() }}
/>
</HeaderButtons>
),