I am trying to navigate screens by pressing on specific images on SearchScreen.js. Each image leads to a different screen. I am currently trying to navigate from the first image to the screen meo_sw.js. However, I am not being able to do so and I don't undersand why. Here is the code of SearchScreen.js:
import React from 'react';
import { ScrollView, StyleSheet, TextInput, Text, View, Image, TouchableOpacity, TouchableWithoutFeedback} from 'react-native';
import { NavigationContainer } from '#react-navigation/native';
function SearchScreen() {
return (
<View style={styles.screen}>
<View style={styles.container}>
<TextInput style={styles.inputBox}
underlineColorAndroid='rgba(0,0,0,0)'
placeholder="Procura aqui"
placeholderTextColor = "black"
selectionColor="black"
keyboardType="default"/>
</View>
<View style={styles.teste}>
<Text style={styles.festivais}>Recomendados</Text>
<ScrollView horizontal={true} showsHorizontalScrollIndicator={false} style={styles.festivais_lista}>
<TouchableOpacity onPress={() => navigate('meo_sw')}>
<Image source={require('../assets/images/meo_sudoeste.png')} style={styles.image}/>
</TouchableOpacity>
<TouchableOpacity onPress={() => this.props.navigation.navigate('vodaf_coura')}>
<Image source={require('../assets/images/vodafone_coura.png')} style={styles.image} />
</TouchableOpacity>
<TouchableOpacity onPress={() => this.props.navigation.navigate('superR_superB')}>
<Image source={require('../assets/images/superbock_superrock.png')} style={styles.image}/>
</TouchableOpacity>
<TouchableOpacity onPress={() => this.props.navigation.navigate('nos_primavera')}>
<Image source={require('../assets/images/nos_primavera.png')} style={styles.image}/>
</TouchableOpacity>
<TouchableOpacity onPress={() => this.props.navigation.navigate('rock_in_rio')}>
<Image source={require('../assets/images/rock_in_rio.png')} style={styles.image}/>
</TouchableOpacity>
<TouchableOpacity onPress={() => this.props.navigation.navigate('edp_cool_jazz')}>
<Image source={require('../assets/images/edp_cooljazz.png')} style={styles.image}/>
</TouchableOpacity>
</ScrollView>
</View>
</View>
);
}
SearchScreen.navigationOptions = {
title: 'Procurar',
};
const styles = StyleSheet.create({
//I took this off because it's irrelevant for the question itself
});
export default SearchScreen;
And here is the screen 'meo_sw.js':
import React from 'react';
import {View, Text, TouchableOpacity, StyleSheet} from 'react-native';
const meo_sw = props => {
return(
<View style={styles.header}>
<Text style={styles.texto}>Meo Sudoeste</Text>
</View>
)
};
const styles=StyleSheet.create({
//Irrelevant
})
export default meo_sw;
The error says simply:
ReferenceError: Can't find variable: navigate
Please help me
UPDATED
This is the MainTabNavigator.js:
import React from 'react';
import { Platform } from 'react-native';
import { createStackNavigator } from 'react-navigation-stack';
import { createBottomTabNavigator } from 'react-navigation-tabs';
import TabBarIcon from '../components/TabBarIcon';
import HomeScreen from '../screens/HomeScreen';
import SearchScreen from '../screens/SearchScreen';
import SettingsScreen from '../screens/SettingsScreen';
import ChatScreen from '../screens/ChatScreen';
import CalendarScreen from '../screens/CalendarScreen';
import meo_sw from '../Eventos/Festivais/meo_sw';
const config = Platform.select({
web: { headerMode: 'screen' },
default: {},
});
//Home
const HomeStack = createStackNavigator(
{
HomeScreen: {screen: HomeScreen},
SearchScreen: {screen: SearchScreen},
ChatScreen: {screen: ChatScreen},
SettingsScreen: {screen: SettingsScreen},
CalendarScreen: {screen: CalendarScreen},
},
config
);
HomeStack.navigationOptions = {
tabBarLabel: 'Home',
tabBarIcon: ({ focused }) => (
<TabBarIcon
focused={focused}
name={
Platform.OS === 'ios'
? `ios-home${focused ? '' : '-outline'}`
: 'md-home'
}
/>
),
};
HomeStack.path = '';
//Search
const SearchStack = createStackNavigator(
{
Search: SearchScreen,
},
config
);
SearchStack.navigationOptions = {
tabBarLabel: 'Procurar',
tabBarIcon: ({ focused }) => (
<TabBarIcon focused={focused} name={Platform.OS === 'ios' ? 'ios-search' : 'md-search'} />
),
};
SearchStack.path = '';
//Chat
const ChatStack = createStackNavigator(
{
Chat: ChatScreen,
},
config
);
ChatStack.navigationOptions = {
tabBarLabel: 'Chat',
tabBarIcon: ({ focused }) => (
<TabBarIcon
focused={focused}
name={
Platform.OS === 'ios'
? `ios-chatboxes${focused ? '' : '-outline'}`
: 'md-chatboxes'
}
/>
),
};
ChatStack.path = '';
//Settings
const SettingsStack = createStackNavigator(
{
Settings: SettingsScreen,
},
config
);
SettingsStack.navigationOptions = {
tabBarLabel: 'Perfil',
tabBarIcon: ({ focused }) => (
<TabBarIcon focused={focused} name={Platform.OS === 'ios' ? 'ios-person' : 'md-person'} />
),
};
SettingsStack.path = '';
//Calendar
const CalendarStack = createStackNavigator(
{
Calendar: CalendarScreen,
},
config
);
CalendarStack.navigationOptions = {
tabBarLabel: 'Calendário',
tabBarIcon: ({ focused }) => (
<TabBarIcon focused={focused} name={Platform.OS === 'ios' ? 'ios-calendar' : 'md-calendar'} />
),
};
CalendarStack.path = '';
//Bottom tab navigator
const tabNavigator = createBottomTabNavigator({
SearchStack,
CalendarStack,
HomeStack,
ChatStack,
SettingsStack
});
tabNavigator.path = '';
export default tabNavigator;
And this is the AppNavigator.js:
import React from 'react';
import { createAppContainer, createSwitchNavigator } from 'react-navigation';
import MainTabNavigator from './MainTabNavigator';
export default createAppContainer(
createSwitchNavigator({
Main: MainTabNavigator,
})
);
Pass navigation object as prop.
function SearchScreen({ navigation }) {
....
}
The use it like
<TouchableOpacity onPress={() => navigation.navigate('meo_sw')}>
<Image source={require('../assets/images/meo_sudoeste.png')} style={styles.image}/>
</TouchableOpacity>
Add the screen to one of your navigators, like the following.
const HomeStack = createStackNavigator(
{
HomeScreen: { screen: HomeScreen },
SearchScreen: { screen: SearchScreen },
ChatScreen: { screen: ChatScreen },
SettingsScreen: { screen: SettingsScreen },
CalendarScreen: { screen: CalendarScreen },
meo_sw: { screen: meo_sw}
},
config
);
HomeStack.navigationOptions = {
tabBarLabel: 'Home',
tabBarIcon: ({ focused }) => (
<TabBarIcon
focused={focused}
name={
Platform.OS === 'ios'
? `ios-home${focused ? '' : '-outline'}`
: 'md-home'
}
/>
),
};
Expo example
your Function is unable to get the props so that its not importing navigation property !!
change the function into class and get the props in class and then try navigating.
try this code
export default class SearchScreen extends Component {
constructor(props) {
super(props);
this.state = { }
}
return (
<View style={styles.screen}>
<View style={styles.container}>
<TextInput style={styles.inputBox}
underlineColorAndroid='rgba(0,0,0,0)'
placeholder="Procura aqui"
placeholderTextColor = "black"
selectionColor="black"
keyboardType="default"/>
</View>
<View style={styles.teste}>
<Text style={styles.festivais}>Recomendados</Text>
<ScrollView horizontal={true} showsHorizontalScrollIndicator={false} style={styles.festivais_lista}>
<TouchableOpacity onPress={() => this.props.navigation.navigate('meo_sw')}>
<Image source={require('../assets/images/meo_sudoeste.png')} style={styles.image}/>
</TouchableOpacity>
<TouchableOpacity onPress={() => this.props.navigation.navigate('vodaf_coura')}>
<Image source={require('../assets/images/vodafone_coura.png')} style={styles.image} />
</TouchableOpacity>
<TouchableOpacity onPress={() => this.props.navigation.navigate('superR_superB')}>
<Image source={require('../assets/images/superbock_superrock.png')} style={styles.image}/>
</TouchableOpacity>
<TouchableOpacity onPress={() => this.props.navigation.navigate('nos_primavera')}>
<Image source={require('../assets/images/nos_primavera.png')} style={styles.image}/>
</TouchableOpacity>
<TouchableOpacity onPress={() => this.props.navigation.navigate('rock_in_rio')}>
<Image source={require('../assets/images/rock_in_rio.png')} style={styles.image}/>
</TouchableOpacity>
<TouchableOpacity onPress={() => this.props.navigation.navigate('edp_cool_jazz')}>
<Image source={require('../assets/images/edp_cooljazz.png')} style={styles.image}/>
</TouchableOpacity>
</ScrollView>
</View>
</View>
);
}
Hope it helps , feel free for doubts.
Related
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.
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
I have to dispatch logoutUser() action from CustomDrawerContentComponent. How can I do that?
I have a StackNavigator as well as Drawer Navigator in my app.
Also there is a CustomDrawerComponent to show the username of authenticated user as well as a sign up button in Drawer. Since it is outside the class, I'm unable to dispatch using props.
MainComponent.js
...other import statements
import {
fetchDishes,
fetchComments,
fetchPromos,
fetchLeaders,
logoutUser,
} from "../redux/ActionCreators";
const mapDispatchToProps = (dispatch) => ({
fetchDishes: () => dispatch(fetchDishes()),
fetchComments: () => dispatch(fetchComments()),
fetchPromos: () => dispatch(fetchPromos()),
fetchLeaders: () => dispatch(fetchLeaders()),
logoutUser: () => dispatch(logoutUser()),
});
const handleSignOut = () => {
//Here I have to dispatch logoutUser() but props.logoutUser() says undefined.
};
const CustomDrawerContentComponent = (props) => (
<ScrollView>
<SafeAreaView
style={styles.container}
forceInset={{ top: "always", horizontal: "never" }}
>
<View style={styles.drawerHeader}>
<View style={{ flex: 1 }}>
<Image
source={require("./images/newlogo.png")}
style={styles.drawerImage}
/>
</View>
<View style={{ flex: 2 }}>
<Text style={styles.drawerHeaderText}>Ristorante Con Fusion</Text>
</View>
</View>
<View style={styles.displayName}>
<Avatar
title={props.screenProps.name.match(/\b(\w)/g).join("")}
rounded
>
{" "}
</Avatar>
<Text style={{ fontSize: 22, marginLeft: 5, color: "#fff" }}>
Hello, {props.screenProps.name}
</Text>
</View>
<DrawerItems {...props} />
<TouchableOpacity onPress={() => handleSignOut()}> //Here I am calling the function
<View style={{ flexDirection: "row", justifyContent: "center" }}>
<Icon name="sign-out" type="font-awesome" size={24} color="blue" />
<Text>Sign Out</Text>
</View>
</TouchableOpacity>
</SafeAreaView>
</ScrollView>
);
const MainNavigator = createDrawerNavigator(
{
Home: {
screen: HomeNavigator,
navigationOptions: {
title: "Home",
drawerLabel: "Home",
drawerIcon: ({ tintColor, focused }) => (
<Icon name="home" type="font-awesome" size={24} color={tintColor} />
),
},
},
...
...
...
{
initialRouteName: "Home",
drawerBackgroundColor: "#D1C4E9",
contentComponent: CustomDrawerContentComponent,
}
);
class Main extends Component {
componentDidMount() {
this.props.fetchDishes();
this.props.fetchComments();
this.props.fetchPromos();
this.props.fetchLeaders();
};
render() {
var displayName = this.props.user.user.displayName;
if (displayName == undefined) displayName = this.props.user.name;
return (
<Fragment>
<View
style={{
flex: 1,
paddingTop:
Platform.OS === "ios" ? 0 : Expo.Constants.statusBarHeight,
}}
>
<MainNavigator screenProps={{ name: displayName }} />
</View>
</Fragment>
);
}
}
export default connect(mapStateToProps, mapDispatchToProps)(Main);
You can use the following to import useDispatch
import { useDispatch } from 'react-redux'
and then call it in your handleSignOut like so:
const handleSignOut = () => {
const dispatch = useDispatch()
dispatch(logoutUser())
//Continue with normal logout and maybe other dispatches...
};
Your component is not connected to redux. You are not using mapDispatchToProps anywhere else besides declaring it. Please use connect() method https://react-redux.js.org/api/connect
I have 2 listview in my homepage (TodoDetail.js and TodoDetailChecked.js) and there is TouchableOpacity's in this listview's rows.. When I click this TouchableOpacity, I want to go to Profile.js page.
But the problem is when I click, it can not find props.navigation.navigate.
I tried to catch logs in componentDidMount but nothing about navigate.
componentDidMount() {
console.log(this.props);
}
Please help me...
Here is the code;
TodoDetail.js
import React, { Component } from 'react';
import { Card, Icon } from 'react-native-elements';
// import Checkbox from '../components/Checkbox';
import { Text, View, TouchableOpacity } from 'react-native';
import * as firebase from 'firebase';
import {
Menu,
MenuOptions,
MenuOption,
MenuTrigger,
} from 'react-native-popup-menu';
class TodoDetail extends Component {
componentDidMount() {
console.log(this.props.navigation.navigate('TodoDetail'));
}
clickText() {
const { todo } = this.props.todos;
// const { navigate } = this.props.navigation;
return (
<TouchableOpacity onPress={this.seeDetail.bind(this)} >
<Text numberOfLines={1}> {todo} </Text>
</TouchableOpacity>
);
}
seeDetail() {
const { navigate } = this.props.navigation;
navigate("Profile", { name: "Jane" });
console.log('click');
}
render() {
//Serverdan çekilenler
const uid = this.props.todos.uid;
const success = this.props.todos.success;
//Tarih olayları
const date = new Date();
const day = date.getDate();
const tomorrow = day + 1;
const year = date.getFullYear();
const month = date.getMonth();
//Style tanımlama
const { container, iconContainer, subContainer } = styles;
if (success === 0) {
return (
<Card>
<View style={container}>
<View style={iconContainer}>
<TouchableOpacity onPress={() => firebase.database().ref(`todos/personal/${uid}/success`).set(1)} >
<Icon name='check-box-outline-blank' />
</TouchableOpacity>
<View style={subContainer}>
{this.clickText()}
</View>
<View style={iconContainer}>
<Menu>
<MenuTrigger>
<Icon name='keyboard-arrow-down' />
</MenuTrigger>
<MenuOptions>
<MenuOption onSelect={() => firebase.database().ref(`todos/personal/${uid}/date`).set({ day, year, month })} >
<Text style={{ color: 'black' }} > Son Tarihi Bugün </Text>
</MenuOption>
<MenuOption onSelect={() => firebase.database().ref(`todos/personal/${uid}/date`).set({ day: tomorrow, year, month })} >
<Text style={{ color: 'black' }} > Son Tarihi Yarın </Text>
</MenuOption>
<MenuOption onSelect={() => firebase.database().ref(`todos/personal/${uid}/date`).remove()} >
<Text style={{ color: 'black' }} > Son Tarihi Kaldır </Text>
</MenuOption>
<MenuOption onSelect={() => firebase.database().ref(`todos/personal/${uid}`).remove()} >
<Text style={{ color: 'red' }} > Yapılacak İşi Sil </Text>
</MenuOption>
</MenuOptions>
</Menu>
</View>
</View>
</View>
</Card>
);
} else
if (success === 1) {
return (
null
);
}
}
}
Todolist.js
createDataSource({ studentsArray }) {
const ds = new ListView.DataSource({
rowHasChanged: (r1, r2) => r1 !== r2
});
this.dataSource = ds.cloneWithRows(studentsArray.reverse());
}
changeScreen() {
this.setState({ screenSize: false });
}
changeScreenBack() {
this.setState({ screenSize: true });
}
renderRow(todos) {
return <TodoDetail todos={todos} />;
}
renderRow2(todos) {
return <TodoDetailChecked todos={todos} />;
}
render() {
// const { navigate } = this.props.navigation;
const { container, inputContainer, inputText } = styles;
if (!this.state.screenSize) {
return (
<View style={container} >
<View style={inputContainer} >
<Icon name={'add'} />
<TextInput
style={inputText}
underlineColorAndroid='transparent'
placeholder="Yapılacak iş ekle..."
placeholderTextColor="#FFFFFF"
value={this.props.todo}
onChangeText={todo => this.props.todoChanged(todo)}
/>
<Button
onPress={this.addToDo.bind(this)}
title="Ekle"
color="#841584"
accessibilityLabel="Learn more about this purple button"
/>
</View>
<View style={{ flex: 1 }}>
<View style={{ flex: 1 }}>
<ListView
enableEmptySections
dataSource={this.dataSource}
renderRow={this.renderRow}
/>
</View>
<View style={{ flex: 1 }}>
<View style={{ height: 1, backgroundColor: 'gray' }} />
<ListView
enableEmptySections
dataSource={this.dataSource}
renderRow={this.renderRow2}
/>
</View>
</View>
<Button
onPress={this.changeScreenBack.bind(this)}
title="Tamamlananları Gizle"
color="#841584"
/>
</View>
);
} else
if (this.state.screenSize) {
return (
<View style={container} >
<View style={inputContainer} >
<Icon name={'add'} />
<TextInput
style={inputText}
underlineColorAndroid='transparent'
placeholder="Yapılacak iş ekle..."
placeholderTextColor="#FFFFFF"
value={this.props.todo}
onChangeText={todo => this.props.todoChanged(todo)}
/>
<Button
onPress={this.addToDo.bind(this)}
title="Ekle"
color="#841584"
/>
</View>
<View style={{ flex: 1 }}>
<ListView
enableEmptySections
dataSource={this.dataSource}
renderRow={this.renderRow}
/>
<Button
onPress={this.changeScreen.bind(this)}
title="Tamamlananları Göster"
color="#841584"
/>
</View>
</View>
);
}
}
}
Router.js
import { StackNavigator } from 'react-navigation';
import Todolist from './src/Todolist';
import Profile from './src/Profile';
import TodoDetail from './components/TodoDetail';
import TodoDetailChecked from './components/TodoDetailChecked';
import TodoPage from './components/TodoPage';
const Router = StackNavigator({
Todolist: { screen: Todolist },
TodoDetail: { screen: TodoDetail },
Profile: { screen: Profile },
TodoDetailChecked: { screen: TodoDetailChecked },
TodoPage: { screen: TodoPage }
});
export default Router;
This problem about parent child problem.
Let's quotes from documentation:
It's important to note that this only happens if the screen is
rendered as a route by React Navigation (for example, in response to
this.props.navigation.navigate). For example, if we render
DetailsScreen as a child of HomeScreen, then DetailsScreen won't be
provided with the navigation prop, and when you press the
"Go to Details... again" button on the Home screen, the app will throw one of
the quintessential JavaScript exceptions "undefined is not an object".
To fix your problem is pass this.props.navigation to child component from higher component.
Let's do example:
App.js
import React from 'react';
import { StyleSheet, Text, View } from 'react-native';
import MyView from './MyView';
import { StackNavigator } from 'react-navigation';
import DetailsScreen from './DetailsScreen';
class App extends React.Component {
render() {
return (
<View style={styles.container}>
<MyView navigation={this.props.navigation} />
<Text>Open up App.js to start working on your app!</Text>
</View>
);
}
}
const styles = StyleSheet.create({
container: {
flex: 1,
backgroundColor: '#fff',
alignItems: 'center',
justifyContent: 'center',
},
});
export default StackNavigator({
Home: {
screen: App,
},
Details: {
screen: DetailsScreen,
}
});
MyView.js
import React from 'react';
import { StyleSheet, Text, ListView } from 'react-native';
import TodoDetail from './TodoDetail';
export default class MyView extends React.Component {
constructor() {
super();
const ds = new ListView.DataSource({ rowHasChanged: (r1, r2) => r1 !== r2 });
this.state = {
dataSource: ds.cloneWithRows(['todo 1', 'todo 2']),
};
}
renderRow(todos) {
return <TodoDetail todos={todos} navigation={this.props.navigation} />;
}
render() {
return (
<ListView
enableEmptySections
dataSource={this.state.dataSource}
renderRow={(rowData) => this.renderRow(rowData)}
/>
);
}
}
TodoDetail.js
import React from 'react';
import { StyleSheet, Text, View, Button } from 'react-native';
export default class TodoDetail extends React.Component {
componentDidMount() {
// console.log(this.props.navigation.navigate('Details'));
}
render() {
return (
<View>
<Text>Todo detail</Text>
<Text>{this.props.todos}</Text>
<Button
title="Go to Details"
onPress={() => this.props.navigation.navigate('Details', { itemDetail: this.props.todos })}
/>
</View>
);
}
}
DetailsScreen.js
import React from 'react';
import { StyleSheet, Text, View } from 'react-native';
export default class DetailsScreen extends React.Component {
componentDidMount() {
console.log(this.props.navigation);
}
render() {
const { params } = this.props.navigation.state;
return (
<View style={{ flex: 1, alignItems: 'center', justifyContent: 'center' }}>
<Text>Details Screen</Text>
<Text>{ params.itemDetail }</Text>
</View>
);
}
}
so in here, you need to pass navigation={this.props.navigation} every child render. If you see MyView component pass navigation props <MyView navigation={this.props.navigation} />.
And inside of it <TodoDetail todos={todos} navigation={this.props.navigation} />, last TodoDetail will available this.props.navigation to access this.props.navigation.navigate.
I am very new to react-native. I am trying to create a drawer using react-navigation. I could use DrawerNavigator but could not show the header/navbar on all the screens. That is why i create a NavScreen component with profile icon, title and back icon. However they are not aligned properly. I need profile icon to be shown on the left side, title on the center and back button on the right side. How can i do this?
Here is my code
const styles = StyleSheet.create({
container: {
marginTop: Platform.OS === 'ios' ? 20 : 10,
},
});
const NavScreen = ({ navigation, banner }) => (
<ScrollView style={styles.container}>
<Text>{banner}</Text>
<Icon
name="ios-contact-outline"
size={30}
color="#000"
onPress={() => navigation.navigate('DrawerOpen')}
/>
<Icon
name="ios-arrow-round-back-outline"
size={30}
color="#000"
onPress={() => navigation.goBack(null)}
/>
</ScrollView>
);
export default NavScreen;
class App extends React.Component {
static navigationOptions = ({ navigation }) => ({
title: `${navigation.state.routeName}`,
drawerTitle: `${navigation.state.routeName}`,
drawerLabel: 'Home',
drawerIcon: ({ whiteColor }) => (
<MaterialIcons name="drafts" size={14} style={{ color: whiteColor }} />
),
})
render() {
const { navigation } = this.props;
return (
<ScrollView>
<NavScreen navigation={navigation} banner={'Main'} />
<Text>Main Screen</Text>
</ScrollView>
);
}
}
export default App;
I need similar to the below image
First, try to build a StackNavigation, at headerRight, and headerLeft you define your custom buttons (the above), now you can very easy customize the align/padding whatever you need with your icons/buttons.
const stackNavigatorConfiguration = {
// set first Screen
initialRouteName: 'Home',
mode: Platform.OS === 'ios' ? 'card' : 'card',
navigationOptions: ({navigation}) => ({
headerRight: <DrawerButton navigation={navigation} />,
headerLeft: <YourProfileButton navigation={navigation} />,
headerBackTitle: null
})
}
const YourProfileButton = ({ navigation }) => (
<TouchableOpacity>
<Ionicons
style={styles.profileButton}
name='ios-menu-outline'
size={32}
onPress={() => navigation.goBack(null)}
/>
</TouchableOpacity>
)
const DrawerButton = ({ navigation }) => (
<TouchableOpacity>
<Ionicons
style={styles.drawerIcon}
name='ios-menu-outline'
size={32}
onPress={() => navigation.navigate('DrawerOpen')}
/>
</TouchableOpacity>
)