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>
),
Related
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.
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
}
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 building an app with the following dependencies:
"dependencies": {
"#react-navigation/bottom-tabs": "^5.8.0",
"#react-navigation/compat": "^5.2.5",
"#react-navigation/material-bottom-tabs": "^5.2.16",
"#react-navigation/material-top-tabs": "^5.2.16",
"#react-navigation/native": "^5.7.3",
"#react-navigation/stack": "^5.9.0",
"expo": "~38.0.8",
"expo-status-bar": "^1.0.2",
"react": "~16.11.0",
"react-dom": "~16.11.0",
"react-native": "https://github.com/expo/react-native/archive/sdk-38.0.2.tar.gz",
"react-native-elements": "^2.0.4",
"react-native-gesture-handler": "^1.7.0",
"react-native-modals": "^0.19.9",
"react-native-reanimated": "^1.10.2",
"react-native-screens": "^1.0.0-alpha.23",
"react-native-web": "~0.11.7",
"react-navigation": "^4.4.0",
"react-navigation-stack": "^2.8.2",
"react-navigation-tabs": "^2.9.0"
},
Let say I have a Stack navigator and a Bottom Tab Navigator. How can I easily navigate from a screen of the bottom tab to a screen of the Stack Navigator?
I found a "solution" which is to add App in my Bottom Tab Navigator, but the problem is it's appearing in the bottom screens, while I dont want that.
Whats the best way to do this?
const Stack = createStackNavigator();
export default function App() {
return (
<NavigationContainer independent={true}>
<Stack.Navigator initialRouteName="Index">
<Stack.Screen name="MyNotes" component={MyNotes} />
<Stack.Screen name="Login" component={Login} />
<Stack.Screen name="Signup" component={Signup} />
<Stack.Screen name="Index" component={Index} />
<Stack.Screen name="PasswordForgot" component={PasswordForgot} />
<Stack.Screen name="BottomNavigation" component={BottomNavigation} />
<Stack.Screen name="ProfileParameters" component={ProfileParameters} />
<Stack.Screen name="MyProfile" component={MyProfile} />
</Stack.Navigator>
</NavigationContainer>
);
}
And a Bottom Tab Navigator:
const Tab = createBottomTabNavigator();
const tabActiveColor = "#EF2D56";
const tabInActiveColor = "#898A8D";
const BottomTabNavigator = () => {
return (
<Tab.Navigator
initialRouteName="MyNotes"
screenOptions={({ route }) => ({
tabBarIcon: ({ focused, color, size }) => {
let tabIcon = "../assets/notes.png";
if (route.name === "MyNotes") {
tabIcon = require("../assets/notes.png");
} else if (route.name === "Feed") {
tabIcon = require("../assets/feed.png");
} else if (route.name === "Discover") {
tabIcon = require("../assets/decouvrir.png");
} else if (route.name === "MyProfile") {
tabIcon = require("../assets/myprofile.png");
}
return (
<Image
source={tabIcon}
resizeMode="contain"
style={{
height: 26.4,
width: 22,
tintColor: focused ? tabActiveColor : tabInActiveColor,
}}
/>
);
},
})}
tabBarOptions={{
style: { zIndex: 110 },
safeAreaInset: { bottom: "never" },
activeTintColor: "#000000",
}}
>
<Tab.Screen
name="MyNotes"
component={MyNotes}
options={{
tabBarLabel: "Notes",
}}
/>
<Tab.Screen
name="Feed"
component={Feed}
options={{
tabBarLabel: "Feed",
}}
/>
<Tab.Screen
name="Discover"
component={Discover}
options={{
tabBarLabel: "Découvrir",
}}
/>
<Tab.Screen
name="MyProfile"
component={MyProfile}
options={{
tabBarLabel: "Profil",
}}
/>
<Tab.Screen name="App" component={App} />
</Tab.Navigator>
);
};
export default BottomTabNavigator;
const Stack = createStackNavigator();
export default function BottomNavigation() {
return (
<NavigationContainer independent={true}>
<BottomTabNavigator />
</NavigationContainer>
);
}
Example of Navigation I want to do: Navigate from the MyProfile screen of the Bottom Tab, to the ProfileParameter screen in the stack navigator.
here is a demo: https://snack.expo.io/#nomi9995/1826cf
use only one NavigationContainer and make bottom tabs part of stack navigator then you can easily move from bottom tabs to stack screens
like this
import * as React from 'react';
import { Text, View, Button } from 'react-native';
import { NavigationContainer } from '#react-navigation/native';
import { createStackNavigator } from '#react-navigation/stack';
import { createBottomTabNavigator } from '#react-navigation/bottom-tabs';
function TestScreen() {
return (
<View style={{ flex: 1, justifyContent: 'center', alignItems: 'center' }}>
<Text>Test!</Text>
</View>
);
}
function HomeScreen(props) {
const gotoTestStackScreen = () => {
props.navigation.navigate('Test');
};
return (
<View style={{ flex: 1, justifyContent: 'center', alignItems: 'center' }}>
<Text>Home!</Text>
<Button title="Go to test stack screen" onPress={gotoTestStackScreen} />
</View>
);
}
function SettingsScreen() {
return (
<View style={{ flex: 1, justifyContent: 'center', alignItems: 'center' }}>
<Text>Settings!</Text>
</View>
);
}
const Tab = createBottomTabNavigator();
function MyTabs() {
return (
<Tab.Navigator>
<Tab.Screen name="Home" component={HomeScreen} />
<Tab.Screen name="Settings" component={SettingsScreen} />
</Tab.Navigator>
);
}
const Stack = createStackNavigator();
export default function App() {
return (
<NavigationContainer>
<Stack.Navigator initialRouteName="Tabs">
<Stack.Screen name="Test" component={TestScreen} />
<Stack.Screen name="Tabs" component={MyTabs} />
</Stack.Navigator>
</NavigationContainer>
);
}
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>
);
}
}