Why is React Native App.js navigation undefined in App.js? - javascript

export default function App ({navigation})
There is a function that starts with and contains <Stack.Navigator>.
But when I want to use the navigation feature and use "navigation.navigate ('Lead') in onPress
TypeError: undefined is not an object evaluating react navigation
I get an error. My English is not very good. Please help me on this topic. Now I'm adding the sample codes to you.
import * as React from 'react';
import { StyleSheet, AsyncStorage, Alert, View, Image, TouchableOpacity } from 'react-native';
import { NavigationContainer } from '#react-navigation/native';
import { createStackNavigator } from '#react-navigation/stack';
import { createBottomTabNavigator } from '#react-navigation/bottom-tabs';
import { ApplicationProvider, Layout, Input, Button, Text, Spinner, IconRegistry, Icon } from '#ui-kitten/components';
import { EvaIconsPack } from '#ui-kitten/eva-icons';
import * as eva from '#eva-design/eva';
import LinkingConfiguration from './navigation/LinkingConfiguration';
import * as axios from 'axios';
import Base64 from './components/Base64';
import LeadScreen from './screens/LeadScreen';
import AddLeadScreen from './screens/AddLeadScreen';
import TabBarIcon from './components/TabBarIcon';
import HomeScreen from './screens/HomeScreen';
import CampaignsScreen from './screens/CampaignsScreen';
import MenuScreen from './screens/MenuScreen';
const Stack = createStackNavigator();
export default function App({ navigation }) {
const logout = async () => {
await AsyncStorage.removeItem('token');
dispatch({ type: 'SIGN_OUT' });
};
return (
<>
<IconRegistry icons={EvaIconsPack} />
<ApplicationProvider {...eva} theme={eva.light}>
<Layout style={styles.container}>
<AuthContext.Provider value={authContext}>
<NavigationContainer linking={LinkingConfiguration}>
<Stack.Navigator>
{state.isLoading ? (
// We haven't finished checking for the token yet
<Stack.Screen name="Splash" component={SplashScreen} options={{ headerShown: false }} />
) : state.token == null ? (
// No token found, user isn't signed in
<>
<Stack.Screen name="Login" component={LoginScreen} options={{ title: 'Oturum Açın' }} />
</>
) : (
// User is signed in
<>
<Stack.Screen name="User" component={UserScreen} options={{
headerStyle: { backgroundColor: '#e8a200' },
headerTintColor: 'white',
headerTitleStyle: { color: '#fff' },
headerRight: () => (
<TouchableOpacity activeOpacity={0.4} underlayColor='transparent' onPress={() => logout() } style={{ marginRight: 12 }}>
<Icon
style={styles.icon}
fill='#FFFFFF'
name='power-outline'
/>
</TouchableOpacity>
)
}} />
<Stack.Screen name="Lead" component={LeadScreen} options={{
title: 'Müşteri Adayları',
headerStyle: { backgroundColor: '#e8a200' },
headerTintColor: 'white',
headerTitleStyle: { fontWeight: 'bold', color: '#fff' },
headerRight: () => (
<TouchableOpacity activeOpacity={0.4} underlayColor='transparent' onPress={ () => console.log(navigation) } style={{ marginRight: 12 }}>
<Icon
style={styles.icon}
fill='#FFFFFF'
name='plus-outline'
/>
</TouchableOpacity>
)}} />
<Stack.Screen name="AddLead" component={AddLeadScreen} options={{ title: 'Müşteri Adayı Ekle' }} />
</>
)}
</Stack.Navigator>
</NavigationContainer>
</AuthContext.Provider>
</Layout>
</ApplicationProvider>
</>
);
}

You can pass the navigation or rout prop into options in the stack.screen like this
options={({navigation})=>({
'Your code here'
})}
I have edited it with your code for you.
<Stack.Screen name="Lead" component={LeadScreen}
options={({ navigation }) => ({
title: 'Müşteri Adayları',
headerStyle: { backgroundColor: '#e8a200' },
headerTintColor: 'white',
headerTitleStyle: { fontWeight: 'bold', color: '#fff' },
headerRight: () => (
<TouchableOpacity activeOpacity={0.4}
underlayColor='transparent' onPress={() =>
console.log(navigation)} style={{ marginRight: 12 }}>
<Icon
style={styles.icon}
fill='#FFFFFF'
name='plus-outline'
/>
</TouchableOpacity>
)
})} />

First, I think the navigation here is unnecessary, you can remove it.
export default function App({ navigation }) {
In your screen components, ie. UserScreen, you can use navigation like so
function UserScreen({navigation}) {
// ...some codes
navigation.navigate('WHERE_TO_GO');
// ...some other codes
}
You could also use navigation without passing it to the props.
First you need to import useNavigation
import { useNavigation } from '#'react-navigation/native'
And then, in your component
function UserScreen() {
const nav = useNavigation();
// ...some codes
nav.navigate('WHERE_TO_GO');
// ...some other codes
}
You could get more details here https://reactnavigation.org/docs/use-navigation/
For the onPress function of Lead screen,
<Stack.Screen name="Lead" component={LeadScreen} options={({ navigation }) => ({
title: 'Müşteri Adayları',
headerStyle: { backgroundColor: '#e8a200' },
headerTintColor: 'white',
headerTitleStyle: { fontWeight: 'bold', color: '#fff' },
headerRight: () => (
<TouchableOpacity activeOpacity={0.4} underlayColor='transparent' onPress={ () => navigation.navigate('WHERE_TO_GO') } style={{ marginRight: 12 }}>
<Icon
style={styles.icon}
fill='#FFFFFF'
name='plus-outline'
/>
</TouchableOpacity>
)})} />

You should use useLinkProps to solve this issue:
import { useLinkProps } from '#react-navigation/stack';
And this is an example on how to write code which uses it:
const LinkButton = ({ to, action, children, ...rest }) => {
const { onPress, ...props } = useLinkProps({ to, action });

I have tried everything but this worked for me.
Make a function in your app.js and pass props then access using props.navigation like below.
function CustomDrawerContent**(props)** {
.....
logOut = () => {
AsyncStorage.clear();
**props.navigation.navigate("Login");**
};
.....
}

Related

How can ı create login authentication from a tab screen using react navigation?

I designed two tab screens. One of them can be accessed by everyone ,we need to login to the other. I am using API to login. If the username and password are correct, the login process is completed. But after logging in , ı cannot switch to the main page screen without refreshing from console. Likewise, when I want to logout , I need to refresh from console. I could not do the opening process directly, I think there is a problem with my stack connections. Stack connection is App.js --> MainTabScreen.js --> SettingScreen.js --> ListScreen.js
1.png - App.js --> MainTabScreen.js
2.png - SettingScreen.js --> ListScreen.js
`
[SplashScreen][1]MainScreen
//App.js
import 'react-native-gesture-handler';
import React , {useEffect} from 'react';
import { StyleSheet } from 'react-native';
//Navigation
import { NavigationContainer } from '#react-navigation/native';
//Mobx
import { observer } from 'mobx-react';
//Store
import { store } from './STORE/index'
//Async
import AsyncStorage from '#react-native-async-storage/async-storage';
//Screens
import MainTabScreen from './SCREENS/TABS/MainTabScreen';
export default observer(() => {
useEffect(() => {
(async () => {
const token = await AsyncStorage.getItem('id_token');
store.setStore('SET_TOKEN', token);
})();
}, []);
return (
<NavigationContainer>
<MainTabScreen/>
</NavigationContainer>
)
})
const styles = StyleSheet.create({});
import React , { useEffect , Component} from 'react';
import { StyleSheet, Image, Text, View ,Dimensions, TextInput} from 'react-native';
import { createBottomTabNavigator } from '#react-navigation/bottom-tabs';
import { createStackNavigator} from '#react-navigation/stack';
//Store
import { store } from '../../STORE/index';
//Async
import AsyncStorage from '#react-native-async-storage/async-storage';
//Screens
import HomeScreen from './HomeScreen';
import SettingScreen from './SettingScreen';
import TestScreen from './TestScreen';
//menuScreens
import WhiteListScreen from '../MENUSCREEN/WhiteListScreen';
import Reports from '../MENUSCREEN/Reports';
import SendNotifications from '../MENUSCREEN/SendNotifications';
//Color
import COLORS from '../../COLOR/color'
//Vectoricons
import { Ionicons } from '#expo/vector-icons';
import { BlurView } from 'expo-blur';
//MainTabScreen.js
const WINDOW_WIDTH = Dimensions.get('window').width;
const WINDOW_HEIGHT = Dimensions.get('window').height;
const HomeStack = createStackNavigator();
const SettingsStack = createStackNavigator();
const TestStack = createStackNavigator();
const Tab = createBottomTabNavigator();
function MainTabScreen({navigation}) {
useEffect(() => {
(async () => {
const token = await AsyncStorage.getItem('id_token');
const ip_address = await AsyncStorage.getItem('ip_address');
store.setStore('SET_TOKEN', token);
store.setStore('SET_IPADDRESS', ip_address);
})();
}, []);
return (
<Tab.Navigator screenOptions={{
tabBarStyle: { position: 'absolute' ,backgroundColor: 'black'},
tabBarBackground: () => (
<BlurView tint="light" intensity={20} style={StyleSheet.absoluteFill} />
),
}} >
<Tab.Screen
name="Home"
component={HomeStackScreen}
options={{
tabBarLabel:'Home',
tabBarLabelStyle: {
fontSize: 12,
},
headerShown: false,
tabBarIcon: ({color, size}) => (
<Ionicons name="home-outline" color={color} size={20}
/>),
tabBarActiveTintColor: COLORS.rawColor,
tabBarInactiveTintColor: 'gray',
}}
>
</Tab.Screen>
<Tab.Screen
name="Setting"
component={SettingStackScreen}
options={{
tabBarLabel:'Settings',
tabBarLabelStyle: {
fontSize: 12,
},
headerShown: false,
tabBarIcon: ({color, size}) => (
<Ionicons name="settings-outline" color={color} size={20}
/>),
tabBarActiveTintColor: COLORS.rawColor,
tabBarInactiveTintColor: 'gray',
}}
/>
<Tab.Screen
name="Test"
component={TestStackScreen}
options={{
tabBarLabel:'Test',
tabBarLabelStyle: {
fontSize: 12,
},
headerShown: false,
tabBarIcon: ({color, size}) => (
<Ionicons name="close" color={color} size={20}
/>),
tabBarActiveTintColor: COLORS.rawColor,
tabBarInactiveTintColor: 'gray',
}}
/>
</Tab.Navigator>
);
};
export default MainTabScreen;
const TestStackScreen = ({ navigation }) => (
<TestStack.Navigator screenOptions={{
headerTransparent: { position: 'absolute' ,backgroundColor: 'black'},
tabBarBackground: () => (
<BlurView tint="light" intensity={30} style={StyleSheet.absoluteFill} />
),
headerTintColor: '#000',
}}>
<TestStack.Screen name="menu" component={TestScreen}
options={{
headerTitle: (props) => ( // App Logo
<Image
style={{ width: Platform.OS === 'ios' ? 120 : 100,
height: Platform.OS === 'ios' ? 100 : 50,
}}
source={require('../../assets/Optima-logo.png')}
resizeMode='contain'
/>),
headerRight: () => (
<Ionicons style={styles.drawerStyle}
name="settings"
color="black"
size={25}
backgroundColor="#E2E7EA"
onPress={() => navigation.openDrawer()}> </Ionicons>
)
}} />
<TestStack.Screen name="WhiteListScreen" component={WhiteListScreen}
options={{
headerTitle: (props) => ( // App Logo
<Image
style={{ width: Platform.OS === 'ios' ? 120 : 100,
height: Platform.OS === 'ios' ? 100 : 50,
}}
source={require('../../assets/Optima-logo.png')}
resizeMode='contain'
/>),
headerRight: () => (
<Ionicons style={styles.drawerStyle}
name="settings"
color="black"
size={25}
backgroundColor="#E2E7EA"
onPress={() => navigation.openDrawer()}> </Ionicons>
)
}} />
<TestStack.Screen name="Reports" component={Reports}
options={{
headerTitle: (props) => ( // App Logo
<Image
style={{ width: Platform.OS === 'ios' ? 120 : 100,
height: Platform.OS === 'ios' ? 100 : 50,
}}
source={require('../../assets/Optima-logo.png')}
resizeMode='contain'
/>),
headerRight: () => (
<Ionicons style={styles.drawerStyle}
name="settings"
color="black"
size={25}
backgroundColor="#E2E7EA"
onPress={() => navigation.openDrawer()}> </Ionicons>
)
}} />
<TestStack.Screen name="SendNotifications" component={SendNotifications}
options={{
headerTitle: (props) => ( // App Logo
<Image
style={{ width: Platform.OS === 'ios' ? 120 : 100,
height: Platform.OS === 'ios' ? 100 : 50,
}}
source={require('../../assets/Optima-logo.png')}
resizeMode='contain'
/>),
headerRight: () => (
<Ionicons style={styles.drawerStyle}
name="settings"
color="black"
size={25}
backgroundColor="#E2E7EA"
onPress={() => navigation.openDrawer()}> </Ionicons>
)
}} />
</TestStack.Navigator>
);
const HomeStackScreen = ({ navigation }) => (
<HomeStack.Navigator screenOptions={{
headerTransparent: { position: 'absolute' ,backgroundColor: 'black'},
tabBarBackground: () => (
<BlurView tint="light" intensity={30} style={StyleSheet.absoluteFill} />
),
headerTintColor: '#000',
}}>
<HomeStack.Screen name="menu" component={HomeScreen}
options={{
headerTitle: (props) => ( // App Logo
<Image
style={{ width: Platform.OS === 'ios' ? 120 : 100,
height: Platform.OS === 'ios' ? 100 : 50,
}}
source={require('../../assets/Optima-logo.png')}
resizeMode='contain'
/>),
headerRight: () => (
<Ionicons style={styles.drawerStyle}
name="settings"
color="black"
size={25}
backgroundColor="#E2E7EA"
onPress={() => navigation.openDrawer()}> </Ionicons>
)
}} />
</HomeStack.Navigator>
);
const SettingStackScreen = ({ navigation }) => (
<SettingsStack.Navigator screenOptions={{
headerTransparent: { position: 'absolute' ,backgroundColor: 'black'},
tabBarBackground: () => (
<BlurView tint="light" intensity={30} style={StyleSheet.absoluteFill}/>
),
headerTintColor: '#000',
}}>
<SettingsStack.Screen name="SettingScreen" component={SettingScreen}
options={{
headerTitle: (props) => ( // App Logo
<Image
style={{ width: Platform.OS === 'ios' ? 120 : 120, height: Platform.OS === 'ios' ? 120 : 120 }}
source={require('../../assets/Optima-logo.png')}
resizeMode='contain'
/>),
headerRight: () => (
<Ionicons style={styles.drawerStyle}
name="settings"
color="black"
size={25}
backgroundColor="#E2E7EA"
onPress={() => navigation.openDrawer()}> </Ionicons>
)
}} />
{/* {store.token ?
<Stack.Screen
options={{headerShown: false}}
name="SignInScreen" component={SignInScreen}/>
:
<Stack.Screen
name="ListScreen" component={ListScreen}/>
} */}
{/* <Stack.Screen
options={{headerShown: false}}
name="SignInScreen" component={SignInScreen}/>
<Stack.Screen
name="ListScreen" component={ListScreen}/>
<Stack.Screen
name="WhiteListScreen" component={WhiteListScreen}/>
*/}
</SettingsStack.Navigator>
);
});
//SettingScreen.js
import React, { useEffect } from "react";
import {
Dimensions,
StyleSheet,
ImageBackground,
View
} from "react-native";
import { ActivityIndicator } from "react-native-paper";
import { createStackNavigator } from "#react-navigation/stack";
//Store
import { store } from "../../STORE/index";
//Color
import COLORS from "../../COLOR/color";
//Screens
import SignInScreen from "../SignInScreen";
import ListScreen from "../TABS/ListScreen";
import CashierSignIn from "../TABS/CashierSignIn";
const WINDOW_WIDTH = Dimensions.get("window").width;
const WINDOW_HEIGHT = Dimensions.get("window").height;
const Stack = createStackNavigator();
const ListStack = createStackNavigator();
const userToken = store.token;
export default function SettingSreen({ navigation }) {
const [isLoading, setIsLoading] = React.useState(true);
useEffect(() => {
setTimeout(() => {
setIsLoading(false);
}, 1000)
}, []);
if (isLoading && !userToken) {
return (
<View>
<ActivityIndicator size="large" />
</View>
)
}
return (
<ImageBackground
source={require("../../IMAGE/background3.png")}
style={{ width: WINDOW_WIDTH, height: WINDOW_HEIGHT }}
>
{!userToken ? (
<Stack.Navigator ListScreen={props => <ListScreen {...props} />}
screenOptions={{ headerShown: false }} >
<Stack.Screen
name="CashierSignIn"
component={CashierSignIn}
/>
<Stack.Screen
name="SignInScreen"
component={SignInScreen}
/>
</Stack.Navigator>
) : (
<ListStack.Navigator screenOptions={{ headerShown: false }}>
<ListStack.Screen
name="ListScreen"
component={ListScreen}
/>
</ListStack.Navigator>
)}
</ImageBackground>
);
}
const styles = StyleSheet.create({});
import React, { Component } from "react";
import {
Text,
View,
Dimensions,
StyleSheet,
ImageBackground,
TouchableOpacity,
} from "react-native";
import { NavigationContainer } from "#react-navigation/native";
import { createStackNavigator } from "#react-navigation/stack";
//Translation
import i18n from "../../TRANSLATION/I18n";
//Store
import { store } from "../../STORE/index";
//SignIn Screen
import SignInScreen from "../SignInScreen";
//Color
import COLORS from "../../COLOR/color";
//Screens
import ListScreen from "./ListScreen";
//CashierSignIn.js
const WINDOW_WIDTH = Dimensions.get("window").width;
const WINDOW_HEIGHT = Dimensions.get("window").height;
const Stack = createStackNavigator();
export default function CashierSignIn({ navigation }) {
return (
<ImageBackground
source={require("../../IMAGE/background3.png")}
style={{ width: WINDOW_WIDTH, height: WINDOW_HEIGHT }}
>
<View style={styles.container}>
<Text style={styles.logo}></Text>
<TouchableOpacity>
<Text style={styles.forgot}></Text>
</TouchableOpacity>
<TouchableOpacity
onPress={() => navigation.navigate("SignInScreen")}
style={styles.loginBtn}
>
<Text style={styles.loginText}> Cashier Sign In </Text>
</TouchableOpacity>
</View>
</ImageBackground>
);
}
//SignInScreen and List Screen
import React, { useState, useEffect } from "react";
import {
View,
Text,
Dimensions,
StyleSheet,
TouchableOpacity,
ImageBackground,
TextInput,
LogBox,
Alert
} from "react-native";
//Axios
import axios from 'axios';
import { ActivityIndicator } from "react-native-paper";
//Store
import { store } from "../STORE/index";
//COLOR
import COLORS from "../COLOR/color";
//Icons
import Icon from "react-native-vector-icons/Ionicons";
//AsyncStorage
import AsyncStorage from '#react-native-async-storage/async-storage';
LogBox.ignoreLogs([
'Require cycle:'
]);
const WINDOW_WIDTH = Dimensions.get("window").width;
const WINDOW_HEIGHT = Dimensions.get("window").height;
export default function SignInScreen({ navigation }) {
const [username, setUsername] = useState("");
const [password, setPassword] = useState("");
const [isLoading, setIsLoading] = React.useState(true);
useEffect(() => {
setTimeout(() => {
setIsLoading(false);
}, 1000)
}, []);
if (isLoading) {
return (
<View>
<ActivityIndicator size="large" />
</View>
)
}
const loginUser = () => {
if (!username.trim() || !password.trim()) {
Alert.alert(
'' + i18n.t('usernamePasswordValid'),
''
[
{ text: i18n.t('ok'), onPress: () => null }
]
);
return;
} else {
axios.get(`http://172.16.55.36:8004/api/values/gettoken?username=${username}&password=${password}`)
.then((response) => {
console.log(response)
AsyncStorage.setItem('id_token', response.data.data).then(() => {
store.setStore('SET_TOKEN', response.data.data)
setIsLoading(true);
})
})
.catch((error) => {
console.log(error);
})
}
}
return (
<ImageBackground
source={require("../IMAGE/background3.png")}
style={{ width: WINDOW_WIDTH, height: WINDOW_HEIGHT }}
>
<View style={styles.header}>
<TouchableOpacity onPress={() => navigation.navigate('CashierSignIn')}>
<Text alignItems="center">
<Icon name="close" color={COLORS.rawColor} size={30} />
</Text>
</TouchableOpacity>
</View>
<View style={styles.container}>
<Text style={styles.logo}>Optima Ticketing App</Text>
<View style={styles.inputView}>
<TextInput
style={styles.inputText}
placeholder="Username"
placeholderTextColor={COLORS.white}
onChangeText={(username) => setUsername(username)}
/>
</View>
<View style={styles.inputView}>
<TextInput
secureTextEntry
style={styles.inputText}
placeholder="Password"
placeholderTextColor={COLORS.white}
onChangeText={(password) => setPassword(password)}
/>
</View>
<TouchableOpacity onPress={() => navigation.navigate('SignUpScreen')}>
<Text style={styles.forgot}>Forgot Password?</Text>
</TouchableOpacity>
{/* <TouchableOpacity onPress={loginUser ? navigation.navigate('ListScreen') : alert("test")} style={styles.loginBtn}> */}
<TouchableOpacity onPress={loginUser} style={styles.loginBtn}>
<Text style={styles.loginText}>LOGIN</Text>
</TouchableOpacity>
<TouchableOpacity>
<Text onPress={() => navigation.navigate('SignUpScreen')}
style={styles.loginText} >Signup</Text>
</TouchableOpacity>
</View>
</ImageBackground>
);
}
import React, { useState } from "react";
import {
View,
Text,
Dimensions,
StyleSheet,
TouchableOpacity,
ImageBackground,
} from 'react-native';
//Store
import { store } from "../../STORE/index";
//AsyncStorage
import AsyncStorage from '#react-native-async-storage/async-storage';
const WINDOW_WIDTH = Dimensions.get('window').width;
const WINDOW_HEIGHT = Dimensions.get('window').height;
function ListScreen({ navigation }) {
return (
<ImageBackground
source={require("../../IMAGE/background3.png")}
style={{ width: WINDOW_WIDTH, height: WINDOW_HEIGHT }}
>
<View style={styles.container}>
<TouchableOpacity onPress={() => navigation.navigate('WhiteListScreen')}>
<Text>White List</Text>
</TouchableOpacity>
<TouchableOpacity >
<Text>2.screen</Text>
</TouchableOpacity>
<TouchableOpacity
onPress={async () => {
await AsyncStorage.removeItem('id_token')
.then(() => store.setStore('SET_TOKEN', null))
.then(() => navigation.goBack())
}}>
<Text style={styles.loginText}> Log Out </Text>
</TouchableOpacity>
</View>
</ImageBackground>
)
}
export default ListScreen;
I would create a context or utility that checks for login status. Then make the drawer conditionally render a login screen/button, or whatever content you'd like, based on that status.

Lifting a state so I can modify it with an onPress

I am trying to figure out how lifting states work. Currently, I am trying to use onPress in a different component to change the state. In the snack demo I provided below, ListHome and MapHome do not respond for some reason, but you will still see what I am trying to accomplish.
I want the map and list "buttons" to accomplish what the "click for this" does.
Demo - No errors with the current implementation, just no response other than the flash from touchable opacity. (Also remember the snack does not respond for some reason. My local device works fine)
EDIT: So to be clear, I want to be able to access and change the state whichComponentToShow from another component. i.e the ListHome Component.
export default class Home extends React.Component {
constructor(props) {
super(props);
this.state = {
visible: true,
whichComponentToShow: 'Screen1',
};
}
goToMap = () => {
this.setState({ whichComponentToShow: 'Screen2' });
};
render(){
if(this.state.whichComponentToShow === 'Screen1'){
return(
<View style={{backgroundColor: '#d1cfcf' ,flex: 1}}>
<ListHome
renderMap = {this.goToMap.bind(this)}
/>
}
}
export default class ListHome extends React.Component {
goToMap = () => {
this.props.renderMap();
}
<TouchableOpacity onPress={() => this.goToMap.bind(this)}>
<View style={styles.conditionalMap}>
<View style={{justifyContent: 'center', alignItems: 'center'}}>
<Text style={{color: 'black', fontSize: scale(15)}}>
Map
</Text>
</View>
</View>
</TouchableOpacity>
import { StatusBar } from 'expo-status-bar';
import React from 'react';
import { StyleSheet, Text, View } from 'react-native';
import { NavigationContainer } from '#react-navigation/native';
import { createStackNavigator } from '#react-navigation/stack';
import { createBottomTabNavigator } from '#react-navigation/bottom-tabs';
import { MaterialCommunityIcons } from '#expo/vector-icons';
import VenueDetailsScreen from './screens/VenueDetails';
import CarouselGallary from './screens/Carousel';
import Home from './screens/Home';
import Friends from './screens/Friends';
import Profile from './screens/Profile';
const Tab = createBottomTabNavigator();
function MyTabs() {
return (
<Stack.Navigator initialRouteName="Home">
<Stack.Screen
name="Home"
component={Home}
options={{ headerShown: false }}
/>
<Stack.Screen
name="VenueDetails"
component={VenueDetailsScreen}
options={{ headerShown: false }}
/>
<Stack.Screen
name="CarouselGallary"
component={CarouselGallary}
options={{ headerShown: false }}
/>
<Stack.Screen
name="Friends"
component={Friends}
options={{ headerShown: false }}
/>
<Stack.Screen
name="Profile"
component={Profile}
options={{ headerShown: false }}
/>
</Stack.Navigator>
);
}
export default function App() {
return (
<NavigationContainer>
<Tab.Navigator
initialRouteName="Home"
screenOptions={{
tabBarActiveTintColor: '#F60081',
tabBarInactiveTintColor: '#4d4d4d',
tabBarStyle: {
backgroundColor: '#d1cfcf',
borderTopColor: 'transparent',
},
}}>
<Tab.Screen
name="Home"
component={MyTabs}
options={{
tabBarLabel: 'Home',
headerShown: false,
tabBarIcon: ({ color, size }) => (
<MaterialCommunityIcons name="home" color={color} size={size} />
),
}}
/>
<Tab.Screen
name="Friends"
component={Friends}
options={{
tabBarLabel: 'Friends',
tabBarIcon: ({ color, size }) => (
<MaterialCommunityIcons
name="account-group"
color={color}
size={size}
/>
),
}}
/>
<Tab.Screen
name="Profile"
component={Profile}
options={{
tabBarLabel: 'Profile',
tabBarIcon: ({ color, size }) => (
<MaterialCommunityIcons
name="account"
color={color}
size={size}
/>
),
}}
/>
</Tab.Navigator>
</NavigationContainer>
);
}
const Stack = createStackNavigator();
What you are trying to achieve is a common use case, which is to update the state in an ancestor component. You essentially have a component tree that looks like this:
You are trying to update the state of the Home component from the ListHome component with the renderMap prop that sets the state of the Home screen. This makes sense, so you have basic principle down, the reason why it is not working is due to a minor mistake in the ListHome component
<View style={styles.conditionalMap}>
<TouchableOpacity onPress={() => this.goToMap.bind(this)}>
// In the above line, change to this.goToMap()
<View style={{ justifyContent: 'center', alignItems: 'center' }}>
<Text style={{ color: 'black', fontSize: scale(15) }}>Map</Text>
</View>
</TouchableOpacity>
</View>
This is what the bind method does:
The bind() method creates a new function that, when called, has this keyword set to the provided value, with a given sequence of arguments preceding any provided when the new function is called.
So the way onPress is currently defined, it will create a new function, but that function is never actually called. Changing this.goToMap.bind(this) to this.goToMap() should solve your problem.

React Native Navigation Drawer Problem ('navigation.openDrawer' is undefined))

Hi guys i'm new to react native. I want to use drawer navigation with menu button. But actually i don't understand react navigation very well probably. When i press button for openDrawer i'm getting error like this;
TypeError: navigation.openDrawer is not a function. (In 'navigation.openDrawer()', 'navigation.openDrawer' is undefined)
This is My Snack Example ; https://snack.expo.io/#vubes/drawer-check
Here is useful part of my code. Maybe you can understand my problem.
Thanks in advance to anyone who can help.
function DovizStack({navigation}) {
return (
<Stack.Navigator
initialRouteName="Döviz"
screenOptions={{
headerStyle: { backgroundColor: "#1D1D1D" },
headerTintColor: "#fff",
headerTitleStyle: { fontWeight: "bold" },
}}
>
<Stack.Screen
name="Doviz"
component={Doviz}
options={{
title: "Döviz",
headerTitleAlign: "center",
headerLeft: () => (<TouchableOpacity style={{paddingLeft:20}} onPress={()=> navigation.openDrawer()}>
<MaterialCommunityIcons name="menu" color={"white"} size={20} />
</TouchableOpacity>),
}}
/>
<Stack.Screen
name="dovizBuyDetails"
component={dovizBuyDetails}
options={{ title: "Alış", headerTitleAlign: "center" }}
/>
<Stack.Screen
name="dovizSellDetails"
component={dovizSellDetails}
options={{ title: "Satış", headerTitleAlign: "center" }}
/>
</Stack.Navigator>
);
}
I have 5 stack like this. After that comes the myTab.
drawerStack ;
function DrawerStack() {
return(
<Drawer.Navigator initialRouteName="Menu" drawerPosition= "right" >
<Drawer.Screen name="stack" component={stack} />
<Drawer.Screen name="Doviz" component={DovizStack}/>
<Drawer.Screen name="Altın" component={AltinStack} />
</Drawer.Navigator>
)
}
and default stack ;
export default function stack() {
return (
<NavigationContainer>
<Stack.Navigator>
<Stack.Screen
options={{ headerShown: false }}
name="Giriş"
component={LandingStack}
/>
<Stack.Screen
options={{ headerShown: false }}
name="drawer"
component={myTab}
/>
</Stack.Navigator>
</NavigationContainer>
);
}
Actually i can run drawer with landingscreen(login page,register) but i don't want to display without login
navigation in not defined in your scope.
use options as function and receive navigation see here.
your code should look like this:
<Stack.Screen
options={({ navigation }) => ({ //receive navigation here
//navigation is defined now you can use it
headerLeft: () => (
<TouchableOpacity
style={{paddingLeft:20}}
onPress={()=> navigation.openDrawer()}>
<MaterialCommunityIcons name="menu" color={"white"} size={20} />
</TouchableOpacity>),
})}
/>
EDIT :
see full example(open drawer menu from nested stack navigation) try snack here
import * as React from 'react';
import { Button, View, Text, TouchableOpacity } from 'react-native';
import { NavigationContainer } from '#react-navigation/native';
import { createStackNavigator } from '#react-navigation/stack';
import { createDrawerNavigator } from '#react-navigation/drawer';
function ProfileScreen({ navigation }) {
return (
<View style={{ flex: 1, alignItems: 'center', justifyContent: 'center' }}>
<Text>Profile Screen</Text>
</View>
);
}
const Drawer = createDrawerNavigator();
const Stack = createStackNavigator();
function DovizStack() {
return (
<Stack.Navigator>
<Stack.Screen
name="Profile"
options={({ navigation }) => ({ //receive navigation here
headerLeft: () => (
<TouchableOpacity style={{paddingLeft:20}} onPress={()=> navigation.openDrawer()}>
<Text>open</Text>
</TouchableOpacity>),
})
}
component={ProfileScreen} />
</Stack.Navigator>
);
}
function DrawerStack() {
return(
<Drawer.Navigator initialRouteName="Doviz">
<Drawer.Screen name="Doviz" component={DovizStack}/>
</Drawer.Navigator>
)
}
export default function App() {
return (
<NavigationContainer>
<DrawerStack/>
</NavigationContainer>
);
}

How to navigate to nested screen in react-native

I am trying to navigate to another screen with in my album component when the user click
on a album but I keep getting this error
The action 'NAVIGATE' with payload {"name":"AlbumScreen"} was not handled by any navigator.
below is my code and my try
navigation->Album->index.tsx
import React from 'react';
import { View, Image, Text, TouchableWithoutFeedback } from 'react-native';
import styles from './style';
import { Album, TabOneParamList } from '../../types';
import { useNavigation } from '#react-navigation/native';
// import Navigation from '../navigation';
export type AlbumProps = {
album: Album,
}
const AlbumComponent = (props: AlbumProps) => {
const navigation = useNavigation();
const onPress = () => {
navigation.navigate('AlbumScreen');
}
return (
<TouchableWithoutFeedback onPress={onPress}>
<View style={styles.container}>
<Image source={{ uri: props.album.imageUri }} style={styles.image} />
<Text style={styles.text}>{props.album.artistsHeadline}</Text>
</View>
</TouchableWithoutFeedback>
);
}
export default AlbumComponent;
here is my AlbumScreen.tsx also this is the screen I want to user to move to once they click on the Album
import React from 'react';
import { View, Text } from 'react-native';
const AlbumScreen = () => (
<View>
<Text style={{ color: 'white' }} >Hello from Album Screen</Text>
</View>
);
export default AlbumScreen;
also here is my BottomTabNavigation which I add the newly created AlbumScreen just the way the HomeScreen is added
import {
Ionicons,
Entypo,
EvilIcons,
MaterialCommunityIcons,
FontAwesome5,
FontAwesome
} from '#expo/vector-icons';
import { createBottomTabNavigator } from '#react-navigation/bottom-tabs';
import { createStackNavigator } from '#react-navigation/stack';
import * as React from 'react';
import Colors from '../constants/Colors';
import useColorScheme from '../hooks/useColorScheme';
import TabOneScreen from '../screens/HomeScreen';
import AlbumScreen from '../screens/AlbumScreen';
import TabTwoScreen from '../screens/TabTwoScreen';
import { BottomTabParamList, TabOneParamList, TabTwoParamList } from '../types';
const BottomTab = createBottomTabNavigator<BottomTabParamList>();
export default function BottomTabNavigator() {
const colorScheme = useColorScheme();
return (
<BottomTab.Navigator
initialRouteName="Home"
tabBarOptions={{ activeTintColor: Colors[colorScheme].tint }}>
<BottomTab.Screen
name="Home"
component={TabOneNavigator}
options={{
tabBarIcon: ({ color }) => <Entypo name="home" size={30} style={{ marginBottom: -3 }} color={color} />,
}}
/>
<BottomTab.Screen
name="store"
component={TabTwoNavigator}
options={{
tabBarIcon: ({ color }) => <MaterialCommunityIcons name="store" size={30} style={{ marginBottom: -3 }} color={color} />,
}}
/>
<BottomTab.Screen
name="Library"
component={TabTwoNavigator}
options={{
tabBarIcon: ({ color }) => <Ionicons name="library-outline" size={30} style={{ marginBottom: -3 }} color={color} />,
}}
/>
<BottomTab.Screen
name="Profile"
component={TabTwoNavigator}
options={{
tabBarIcon: ({ color }) => <FontAwesome name="user-circle" size={28} style={{ marginBottom: -3 }} color={color} />,
}}
/>
</BottomTab.Navigator>
);
}
// Each tab has its own navigation stack, you can read more about this pattern here:
// https://reactnavigation.org/docs/tab-based-navigation#a-stack-navigator-for-each-tab
const TabOneStack = createStackNavigator<TabOneParamList>();
function TabOneNavigator() {
return (
<TabOneStack.Navigator>
<TabOneStack.Screen
name="TabOneScreen"
component={TabOneScreen}
options={{ headerTitle: 'Home' }}
/>
<TabOneStack.Screen
name="AlbumScreen"
component={AlbumScreen}
options={{ headerTitle: 'Album' }}
/>
</TabOneStack.Navigator>
);
}
const TabTwoStack = createStackNavigator<TabTwoParamList>();
function TabTwoNavigator() {
return (
<TabTwoStack.Navigator>
<TabTwoStack.Screen
name="TabTwoScreen"
component={TabTwoScreen}
options={{ headerTitle: 'Tab Two Title' }}
/>
</TabTwoStack.Navigator>
);
}
Here is the picture of what I am trying to do I want upon clicking on the album on the right of this image the user is direct to another screen but I keep getting the Highlighted error my errors
You will need to specify which stack you are targeting when you attempt to navigate.
https://reactnavigation.org/docs/nesting-navigators/#navigating-to-a-screen-in-a-nested-navigator

ReferenceError: Can't find variable: navigation

So what I'm trying to do is that I'd like the DrawerNavigator to be accessed by selecting the icon on the top left . Im using react nav 5 for this. I keep recieving the error displayed above.
I've tried doing this using this.props.navigation but that also did not seem to work.
Assistance would be greatly appreciared
AppNavigator:
/* eslint-disable no-unused-expressions */
import React, { useState, useEffect } from 'react'
import { NavigationContainer, DrawerActions } from '#react-navigation/native'
import { createStackNavigator } from '#react-navigation/stack'
import auth from '#react-native-firebase/auth'
import {IconButton} from 'react-native-paper'
import Login from '../components/login'
import Signup from '../components/signup'
import forgotPassword from '../components/forgotPassword'
import DashboardScreen from '../screens/DashboardScreen'
const Stack = createStackNavigator()
export default function MyStack() {
// Set state while Firebase Connects
const [starting, setStarting] = useState(true)
const [user, setUser] = useState()
// Handle state changes for user
function onAuthStateChanged(user) {
setUser(user)
if (starting) setStarting(false)
}
useEffect(() => {
const subcriber = auth().onAuthStateChanged(onAuthStateChanged)
return subcriber
// unsub on mount
}, [])
if (starting) return null
if (!user) {
return (
<NavigationContainer>
<Stack.Navigator
screenOptions={{
headerTitleAlign: 'center',
headerStyle: {
backgroundColor: '#3740FE',
},
headerTintColor: '#fff',
headerTitleStyle: {
fontWeight: 'bold',
},
}}
>
<>
<Stack.Screen
name="Login"
component={Login}
/>
<Stack.Screen
name="Signup"
component={Signup}
/>
<Stack.Screen
name="ForgotPassword"
component={forgotPassword}
/>
</>
</Stack.Navigator>
</NavigationContainer>
)
}
return (
<NavigationContainer>
<Stack.Navigator
screenOptions={{
headerTitleAlign: 'center',
headerStyle: {
backgroundColor: '#3740FE',
},
headerTintColor: '#fff',
headerTitleStyle: {
fontWeight: 'bold',
},
}}
>
<>
<Stack.Screen
name="Dashboard"
component={DashboardScreen}
options={{
headerLeft: props =>
<IconButton
{...props}
icon="menu"
color="white"
onPress={() => navigation.dispatch(DrawerActions.toggleDrawer())}
/>,
headerRight: props =>
<IconButton
{...props}
icon="magnify"
color="white"
/>
}}
/>
</>
</Stack.Navigator>
</NavigationContainer>
)
}
Dashboard:
import 'react-native-paper'
import React from 'react';
import { StyleSheet, View} from 'react-native';
import {Button} from 'react-native-paper'
import { createDrawerNavigator } from '#react-navigation/drawer'
function HomeScreen ({navigation}) {
return (
<View>
<Button
onPress={() => navigation.navigate('Settings')}
/>
</View>
);
}
function SettingsScreen ({navigation}) {
return (
<View> style={styles.container}
<Text>
TESTING
</Text>
</View>
);
}
const Drawer = createDrawerNavigator();
export default function DashboardScreen (){
return (
<Drawer.Navigator initialRouteName="Home">
<Drawer.Screen name="Home" component={HomeScreen}/>
<Drawer.Screen name="Settings" component={SettingsScreen}/>
</Drawer.Navigator>
);
}
const styles = StyleSheet.create({
container: {
flex: 1,
display: "flex",
justifyContent: 'center',
alignItems: 'center',
padding: 35,
backgroundColor: '#fff'
},
textStyle: {
fontSize: 15,
marginBottom: 20
}
});
you can get it when you write the options in function like
<Stack.Screen
name="Dashboard"
component={DashboardScreen}
options={({navigation})=>({
headerLeft: props =>
<IconButton
{...props}
icon="menu"
color="white"
onPress={() => navigation.dispatch(DrawerActions.toggleDrawer())}
/>
})}
/>

Categories

Resources