Stack navigator not working in release apk - react-native

Here I am trying to implement a nested navigation in which I have
A bottom tab navigator
A couple of other screens.
My app is working fine in debug mode the following pop up is working on debug mode.
But it is not working when I releases the apk. I am using react navigation v5. Nothing happens when I tap on the button in released apk.
Main Navigation
import * as React from 'react';
import { NavigationContainer } from '#react-navigation/native';
import { createStackNavigator } from '#react-navigation/stack';
import Dashboard from '../screens/Dashboard';
import BottomTabs from './BottomTab';
import CreateTodo from '../screens/CreateTodo';
import EditTodo from '../screens/EditTodo';
const Stack = createStackNavigator();
const MainNav = () => {
return (
<NavigationContainer>
<Stack.Navigator
mode={'card'}
screenOptions={{
cardStyle: { backgroundColor: 'transparent' },
cardOverlayEnabled: true,
cardStyleInterpolator: ({ current: { progress } }) => ({
cardStyle: {
opacity: progress.interpolate({
inputRange: [0, 0.5, 0.9, 1],
outputRange: [0, 0.25, 0.7, 1],
}),
},
overlayStyle: {
opacity: progress.interpolate({
inputRange: [0, 1],
outputRange: [0, 0.5],
extrapolate: 'clamp',
}),
},
}),
}}
initialRouteName='BottomTabs'
headerMode={'none'}
// options={{ headerShown: false }}
>
<Stack.Screen name="BottomTabs" component={BottomTabs} />
<Stack.Screen name="CreateTodo" component={CreateTodo} />
<Stack.Screen name="EditTodo" component={EditTodo} />
</Stack.Navigator>
</NavigationContainer>
);
}
export default MainNav;
Bottom Tab Navigation
import * as React from 'react';
import {createMaterialBottomTabNavigator} from '#react-navigation/material-bottom-tabs';
import {
widthPercentageToDP as wp,
heightPercentageToDP as hp,
} from 'react-native-responsive-screen';
import FontAwesome from 'react-native-vector-icons/FontAwesome';
import Ionicons from 'react-native-vector-icons/Ionicons';
import AntDesign from 'react-native-vector-icons/AntDesign';
import Settings from './../screens/Settings';
import Dashboard from './../screens/Dashboard';
import Profile from './../screens/Profile';
const Tab = createMaterialBottomTabNavigator();
const BottomTabs = () => {
return (
<Tab.Navigator
initialRouteName="Dashboard"
activeColor="white"
shifting={true}
barStyle={{
fontFamily: 'Lato-Black',
}}>
<Tab.Screen
name="Dashboard"
component={Dashboard}
options={{
tabBarLabel: 'Dashboard',
fontFamily: 'Lato-Black',
tabBarColor: '#6C70F4',
tabBarIcon: ({color}) => (
<FontAwesome name="tasks" color={color} size={wp(5.5)} />
),
}}
/>
<Tab.Screen
name="Settings"
component={Settings}
options={{
tabBarLabel: 'Settings',
tabBarColor: 'red',
tabBarIcon: ({color}) => (
<Ionicons name="md-settings" color={color} size={wp(5.5)} />
),
}}
/>
<Tab.Screen
name="Profile"
component={Profile}
options={{
tabBarLabel: 'Profile',
tabBarColor: 'teal',
tabBarIcon: ({color}) => (
<AntDesign name="profile" color={color} size={wp(5.5)} />
),
}}
/>
</Tab.Navigator>
);
};
export default BottomTabs;
package.json
{
"name": "App Name",
"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.10",
"#react-navigation/material-bottom-tabs": "^5.2.7",
"#react-navigation/native": "^5.4.2",
"#react-navigation/stack": "^5.4.2",
"react": "16.11.0",
"react-native": "0.62.2",
"react-native-gesture-handler": "^1.6.1",
"react-native-paper": "^3.10.1",
"react-native-reanimated": "^1.8.0",
"react-native-responsive-screen": "^1.4.1",
"react-native-safe-area-context": "^1.0.2",
"react-native-screens": "^2.7.0",
"react-native-vector-icons": "^6.6.0"
},
"devDependencies": {
"#babel/core": "^7.9.6",
"#babel/runtime": "^7.9.6",
"#react-native-community/eslint-config": "^1.1.0",
"babel-jest": "^26.0.1",
"eslint": "^7.0.0",
"jest": "^26.0.1",
"metro-react-native-babel-preset": "^0.59.0",
"react-test-renderer": "16.11.0"
},
"jest": {
"preset": "react-native"
}
}

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
}

Error : Invariant Violation: TurboModuleRegistry.getEnforcing(...): 'NativeReanimated' could not be found

I followed this tutorial https://medium.com/#ritikjain1272/making-drawer-navigator-and-a-splash-screen-on-your-react-native-app-2fb561ee17f1 And I have been able to work on several Mobile Apps in the past. Which compiled to APK and uploaded to playstore, but this was in the past.
Trying since today and its been very impossible to get it to work as the very usual.
I keep getting this Error
Invariant Violation: TurboModuleRegistry.getEnforcing(...):
'NativeReanimated' could not be found. Verify that a module by this
name is registered in the native binary.
My code is looking like this for App.js
import {createAppContainer, createSwitchNavigator} from 'react-navigation';
import {createStackNavigator} from 'react-navigation-stack';
import {createDrawerNavigator} from 'react-navigation-drawer';
import Icon from 'react-native-vector-icons/SimpleLineIcons';
import Splash from './src/Splash';
import Login from './src/Login';
import Register from './src/Register';
import Dashboard from './src/Dashboard';
import InstantMessage from './src/InstantMessage';
const LoginNavigator = createStackNavigator({
'Login': {
screen: Login,
navigationOptions: ({navigation}) => ({
headerLeft: () => (
<TouchableOpacity
style={{marginLeft: 20}}
onPress={() => navigation.toggleDrawer()}>
<Icon name="menu" size={12} />
</TouchableOpacity>
),
}),
},
});
const RegisterNavigator = createStackNavigator({
'Register': {
screen: Register,
navigationOptions: ({navigation}) => ({
headerLeft: () => (
<TouchableOpacity
style={{marginLeft: 20}}
onPress={() => navigation.toggleDrawer()}>
<Icon name="menu" size={12} />
</TouchableOpacity>
),
}),
},
});
const DashboardNavigator = createStackNavigator({
'Home': {
screen: Dashboard,
navigationOptions: ({navigation}) => ({
headerLeft: () => (
<TouchableOpacity
style={{marginLeft: 20}}
onPress={() => navigation.toggleDrawer()}>
<Icon name="menu" size={12} />
</TouchableOpacity>
),
}),
},
});
const InstantMessageNavigator = createStackNavigator({
'Instant Message': {
screen: InstantMessage,
navigationOptions: ({navigation}) => ({
headerLeft: () => (
<TouchableOpacity
style={{marginLeft: 20}}
onPress={() => navigation.toggleDrawer()}>
<Icon name="menu" size={12} />
</TouchableOpacity>
),
}),
},
});
const DrawerNavigator = createDrawerNavigator({
Dashboard: {
navigationOptions: {
drawerIcon: (
<Image
source={{uri: 'asset:/icons/megaphone.png'}}
style={{width: 21, height: 21}}
/>
),
drawerLabel: 'Home',
},
screen: DashboardNavigator,
},
InstantMessage: {
navigationOptions: {
drawerIcon: (
<Image
source={{uri: 'asset:/icons/megaphone.png'}}
style={{width: 21, height: 21}}
/>
),
drawerLabel: 'Messages',
},
screen: DashboardNavigator,
},
});
const AppSwitchNavigator = createSwitchNavigator(
{
Splash: {screen: Splash},
Login: {screen: Login},
Drawer: {screen: DrawerNavigator},
},
{
initialRouteName: 'Splash',
},
);
const App = createAppContainer(AppSwitchNavigator);
export default App;
And package.json is looking like this
{
"name": "xxxxxxxxx",
"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.10",
"#react-native-picker/picker": "^1.9.8",
"react": "16.13.1",
"react-native": "0.63.4",
"react-native-gesture-handler": "^1.9.0",
"react-native-hr": "^1.1.4",
"react-native-hr-component": "^2.0.3",
"react-native-picker-select": "^8.0.4",
"react-native-reanimated": "^1.13.2",
"react-native-safe-area-context": "^3.1.9",
"react-native-screens": "^2.16.1",
"react-native-vector-icons": "^7.1.0",
"react-navigation": "^4.4.3",
"react-navigation-drawer": "^2.6.0",
"react-navigation-stack": "^2.10.2"
},
"devDependencies": {
"#babel/core": "7.12.10",
"#babel/runtime": "7.12.5",
"#react-native-community/eslint-config": "1.1.0",
"babel-jest": "25.5.1",
"eslint": "6.8.0",
"jest": "25.5.4",
"metro-react-native-babel-preset": "0.59.0",
"react-test-renderer": "16.13.1"
},
"jest": {
"preset": "react-native"
}
}
What Can I be possibly doing wrong? I honestly need help. This is a React Native CLI project.
I solved this issue.
You need to install both Libraries with these Versions
react-native-reanimated": "^1.13.2"
"#react-navigation/drawer": "^5.11.4"
This absolutely works for me
I solved this issue by downgrading react-native-reanimated
If your using npm do this:
npm install react-native-reanimated#1.9.9
if your using yarn do this:
yarn upgrade react-native-reanimated#1.9.9
if you want to do it manually change the version react-native-reanimated to react-native-reanimated: ^1.9.9 in package.json then run npm install or yarn add
I got the same issue "Image Loader" in place of "NativeReanimated"
I just stopped the debugger and did the Hard reload with an empty catch on the chrome browser.
It works fine then

Drawer not changing position from left to right

I am trying to shift drawer from left to right, but it isn't working. However when I am trying to shift from right to left, its working fine. I have already tried in physical device and running in emulator, but nothing worked.
Here is my package.json:
{
"name": "Practice",
"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.10",
"#react-navigation/core": "^5.10.0",
"#react-navigation/drawer": "^5.8.2",
"#react-navigation/native": "^5.5.1",
"react": "16.11.0",
"react-native": "0.62.2",
"react-native-gesture-handler": "^1.6.1",
"react-native-reanimated": "^1.9.0",
"react-native-safe-area-context": "^3.0.5",
"react-native-screens": "^2.8.0"
},
"devDependencies": {
"#babel/core": "^7.10.2",
"#babel/runtime": "^7.10.2",
"#react-native-community/eslint-config": "^2.0.0",
"babel-jest": "^26.0.1",
"eslint": "^7.2.0",
"jest": "^26.0.1",
"metro-react-native-babel-preset": "^0.59.0",
"react-test-renderer": "16.11.0"
},
"jest": {
"preset": "react-native"
}
}
Node Version: v10.19.0
NPM Version: 6.14.5
Code:
import React, {Component} from 'react';
import { Button, View, Text } from 'react-native';
import {createDrawerNavigator, DrawerItem} from '#react-navigation/drawer';
import { NavigationContainer } from '#react-navigation/native';
function HomeScreen({ navigation, route:{params: {changePosition}} }) {
return (
<View style={{ flex: 1, alignItems: 'center', justifyContent: 'center' }}>
<Button
onPress={() => navigation.toggleDrawer()}
title="Open Drawer"
/>
<View style={{marginTop:20}}/>
<Button
onPress={changePosition}
title={'Change Drawer Position'}
/>
</View>
);
}
const Drawer = createDrawerNavigator();
export default class App extends Component {
state = {
position: 'left'
}
changePosition(){
this.setState({position: this.state.position==='right'?'left':'right'}, ()=>{
alert("Drawer Position: " + this.state.position);
});
}
render(){
return (
<NavigationContainer>
<Drawer.Navigator drawerPosition={this.state.position} initialRouteName="Home">
<Drawer.Screen name="Home" component={HomeScreen}
initialParams={{changePosition:this.changePosition.bind(this)}} />
</Drawer.Navigator>
</NavigationContainer>
);
}
}
Screenshot
I have submitted this issue to GitHub repo too track it here:
https://github.com/react-navigation/react-navigation/issues/8374

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

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

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