I added stack and bottom navigator in my app, and it is running correctly. But if I add drawer navigation then I am getting error
Below I have added my files
App.tsx:
import {NavigationContainer} from '#react-navigation/native';
import MainNavigator from '../src/navigator/MainNavigator';
import 'react-native-gesture-handler';
const App = () => {
return (
<NavigationContainer>
<MainNavigator />
</NavigationContainer>
);
};
MainNavigator.tsx:
import {createNativeStackNavigator} from '#react-navigation/native-stack';
import MyTabs from './TabNavigator';
const MainStack = createNativeStackNavigator();
const MainNavigator = () => {
return (
<MainStack.Navigator initialRouteName='StartupScreen'>
<MainStack.Screen
name='StartupScreen'
component={StartupScreen}
/>
<MainStack.Screen
name={'Main'}
component={MyTabs}
/>
</MainStack.Navigator>
);
};
TabNavigator.tsx: I have added drawer in this file
import {createBottomTabNavigator} from '#react-navigation/bottom-tabs';
import {createDrawerNavigator} from '#react-navigation/drawer';
const Drawer = createDrawerNavigator();
function DrawerNavigator() {
return (
<Drawer.Navigator>
<Drawer.Screen name="ReferScreen" component={ReferScreen} />
<Drawer.Screen name="OtherScreen" component={OtherScreen} />
</Drawer.Navigator>
);
}
const iconSize = 24;
const Tab = createBottomTabNavigator();
function MyTabs() {
return (
<Tab.Navigator initialRouteName="HomeScreen">
<Tab.Screen
name="HomeScreen"
component={HomeScreen}
options={{
headerTitle: '',
headerShown: false,
tabBarIcon: props =>
props.focused ? (
<ImageConfig.HomeIconOn height={iconSize} width={iconSize} />
) : (
<ImageConfig.HomeIconOff height={iconSize} width={iconSize} />
),
}}
/>
<Tab.Screen
name="ProfileScreen"
component={ProfileScreen}
options={{
tabBarIcon: props =>
props.focused ? (
<ImageConfig.SettingIconOn height={iconSize} width={iconSize} />
) : (
<ImageConfig.SettingIconOff height={iconSize} width={iconSize} />
),
}}
/>
<Tab.Screen name="drawer" component={DrawerNavigator} />
</Tab.Navigator>
);
}
and following are my dependencies in package.json:
"dependencies": {
"#react-navigation/bottom-tabs": "^6.5.5",
"#react-navigation/drawer": "^6.6.0",
"#react-navigation/native": "^6.1.3",
"#react-navigation/native-stack": "^6.9.9",
"react": "17.0.2",
"react-native": "0.68.5",
"react-native-gesture-handler": "^2.9.0",
"react-native-reanimated": "^2.14.4",
"react-native-safe-area-context": "^4.5.0",
"react-native-screens": "^3.19.0",
},
I am getting this error:
Invariant Violation: Module AppRegistry is not a registered callable module (calling runApplication). A frequent cause of the error
is that the application entry file path is incorrect.
This can also happen when the JS bundle is corrupt or there is an early initialization error when loading React Native.
Related
Been trying to implement #react-navigation/drawer with #react-navigation/native-stack and forcing the app to be RTL, using Expo.
App.tsx:
import { I18nManager } from 'react-native'
import { SafeAreaProvider } from 'react-native-safe-area-view'
import {useLoading} from '#hooks'
I18nManager.forceRTL(true)
I18nManager.allowRTL(true)
export default function App() {
const isLoadingComplete = useLoading()
if (!isLoadingComplete) {
return null
} else {
return (
<SafeAreaProvider style={{flex:1}}>
<Navigation />
<StatusBar style="dark" />
</SafeAreaProvider>
)
}
}
Navigation.tsx:
import { createNativeStackNavigator, NativeStackNavigationOptions } from '#react-navigation/native-stack'
import { createDrawerNavigator } from '#react-navigation/drawer'
import { NavigationContainer } from '#react-navigation/native'
const Stack = createNativeStackNavigator<RootStackParamList>()
const Drawer = createDrawerNavigator<RootDrawerParamList>()
function RootNavigator() {
return (
<Stack.Navigator screenOptions={{presentation: 'modal', headerShown: false}}>
<Stack.Screen name="Login" component={LoginScreen} />
<Stack.Screen name="Root" component={DrawerNavigator} />
<Stack.Screen name="Customer" component={CustomerScreen} />
</Stack.Navigator>
)
}
function DrawerNavigator() {
return (
<View style={styles.container}>
<Drawer.Navigator initialRouteName='Customers' screenOptions={{headerRight: Logout}}>
<Drawer.Screen name="Home" component={HomeScreen} options={{title: Lang.Navigation.Home}} />
<Drawer.Screen name="Customers" component={CustomersScreen} options={{title: Lang.Navigation.Customers}} />
</Drawer.Navigator>
</View>
)
}
export default function Navigation() {
return (
<NavigationContainer ref={navigationRef} linking={LinkingConfiguration}>
<RootNavigator />
</NavigationContainer>
)
}
Dependencies:
"#react-navigation/drawer": "^6.1.8",
"#react-navigation/native": "^6.0.6",
"#react-navigation/native-stack": "^6.2.5",
"expo": "~44.0.0",
"react": "17.0.1",
"react-native": "0.64.3",
"react-native-safe-area-view": "^1.1.1",
The result i'm getting when clicking on the menu built-in hamburger is that the screen does become grayish but the menu never pops in. Using inspect I found that there is a problem with the menu's "left" and "translateX" settings automatically given by the react navigation plugin.
Everything works well when removing the 'ForceRTL' part, but I need the app the be RTL.
instead of using the following code.
I18nManager.forceRTL(true)
I18nManager.allowRTL(true)
fix for this issue is to use direction:'rtl' in the style of Root level component. sample working code demo https://snack.expo.dev/PIIGNx70v
sample code
import * as React from 'react';
import { Button, View } from 'react-native';
import { createDrawerNavigator } from '#react-navigation/drawer';
import { NavigationContainer } from '#react-navigation/native';
function HomeScreen({ navigation }) {
return (
<View style={{ flex: 1, alignItems: 'center', justifyContent: 'center' }}>
<Button onPress={navigation.openDrawer} title="Open drawer" />
</View>
);
}
const Drawer = createDrawerNavigator();
export default function App() {
return (
<View style={{ flex: 1, direction: 'rtl' }}>
<NavigationContainer>
<Drawer.Navigator drawerPosition="right" initialRouteName="Home">
<Drawer.Screen name="Home" component={HomeScreen} />
</Drawer.Navigator>
</NavigationContainer>
</View>
);
}
I am trying to nest a stack navigation inside a drawer navigation on snack expo. I asked this question before and was told to do it all over again. I did and still got errors. Initially I used a class, so I tried using a function instead . I would really appreciate if someone could explain what am I doing wrong? I can also post the link to my project if this helps https://snack.expo.io/#andreeam/it-in-the-valley
The error I get is
Device: (0:0) Cannot assign to read only property 'exports' of object '#<Object>'
Evaluating module://react-native-screens.js
Evaluating module://#react-navigation/drawer.js
Evaluating module://App.js.js
Loading module://App.js
Thank you
This is my code
import * as React from 'react';
import { createStackNavigator } from '#react-navigation/stack';
import { NavigationContainer } from '#react-navigation/native';
import { createDrawerNavigator } from '#react-navigation/drawer';
import SignIn from './components/SignIn';
import ForgotPassword from './components/ForgotPassword';
import Dashboard from './components/Dashboard';
import Advertisers from './components/advertisers';
import Adverts from './components/Adverts';
import Stats from './components/Stats';
import Plans from './components/Plans';
import About from './components/about';
import ManageAdvert from './components/ManageAdvert';
const Stack = createStackNavigator();
function Root () {
return (
<Stack.Navigator
initialRouteName="SignIn"
screenOptions={{
headerTitleAlign: 'center',
headerStyle: { backgroundColor: '#2d3436'},
headerTintColor: '#fff',
headerTitleStyle: { fontWeight: 'bold'}
}}>
<Stack.Screen
name="Reset your password"
component={ForgotPassword}
options={
{title: 'Reset your password'},
{headerLeft: null}
}
/>
<Stack.Screen
name="SignIn"
component={SignIn}
options = {
{headerShown: false,
title: 'SignOut'}
}
/>
<Stack.Screen
name="Dashboard"
component={Dashboard}
/>
<Stack.Screen
name="Advertisers"
component={Advertisers}
options={
{title: 'Advertisers'}
}
/>
<Stack.Screen
name="Adverts"
component={Adverts}
options={
{title: 'Adverts'}
}
/>
<Stack.Screen
name="Stats"
component={Stats}
options={
{title: 'Stats'}
}
/>
<Stack.Screen
name="Plans"
component={Plans}
options={
{title: 'Plans'}
}
/>
<Stack.Screen
name="Manage Adverts"
component={ManageAdvert}
options={
{title: 'Manage Adverts'}
}
/>
</Stack.Navigator>
);
}
const Drawer = createDrawerNavigator();
export default function App () {
return (
<NavigationContainer>
<Drawer.Navigator initialRouteName="Root">
<Drawer.Screen name="Root" component={Root} />
<Drawer.Screen name="About" component={About} />
</Drawer.Navigator>
</NavigationContainer>
);
}
Fixed that, see snack here => https://snack.expo.io/#mustafaskir/ee857b
just updated packages in package.json, should fix that
here's what packages i updated, and i have to republish in my acc
"react-native-paper": "^3.10.1",
"react-native-screens": "^2.4.0",
"#react-navigation/stack": "^5.3.7",
"react-native-reanimated": "^1.8.0",
"#react-navigation/drawer": "^5.7.5",
"#react-navigation/native": "^5.4.0",
"react-native-safe-area-context": "^0.7.3",
"#react-native-community/masked-view": "^0.1.7"
In the latest version of react-navigation v5 how to combine createStackNavigator with createDrawerNavigator
This is my main navigator file.
import InitialScreen from '#InitialScreen'
import SignIn from '#SignIn'
import Home from '#Home'
import {NavigationContainer} from '#react-navigation/native';
import {createStackNavigator} from '#react-navigation/stack';
import { createDrawerNavigator } from '#react-navigation/drawer';
const Drawer = createDrawerNavigator();
const Stack = createStackNavigator();
class NavigationStack extends Component {
render() {
return (
<NavigationContainer>
<Stack.Navigator initialRouteName="Home">
<Stack.Screen name="InitialScreen" component={InitialScreen} options={{ headerShown: false }}/>
<Stack.Screen name="SignIn" component={SignIn} options={{ headerShown: false }} />
<Stack.Screen name="Home" component={Home} options={{ headerShown: false }} />
</Stack.Navigator>
</NavigationContainer>
);
}
}
export default NavigationStack;
In my Home component I have bottom-tabs
import { NavigationContainer } from '#react-navigation/native';
import { createBottomTabNavigator } from '#react-navigation/bottom-tabs';
const Tab = createBottomTabNavigator();
class Home extends Component {
render() {
return (
<Tab.Navigator>
<Tab.Screen
name="Documents"
component={Images}
options={{
tabBarLabel: 'Images',
tabBarIcon: ({ focused }) => (
<Image source={Images.iconDocuments}/>
),
}}
/>
<Tab.Screen
name="Profile"
component={Profile}
options={{
tabBarLabel: 'IRROP',
tabBarIcon: ({ focused }) => (
<Image source={Images.iconImages}/>
),
}}
/>
</Tab.Navigator>
)
}
}
export default Home;
I want to include Drawer Navigation in Stack Navigation How can I do it in react-navigation v5
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());
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>
),