Related
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");**
};
.....
}
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.
I'm using createBottomTabNavigator and listing all my pages there in a file called Navigator.js. The problem is that i have one page called 'AboutScreen' and i don't want to show in the TabNavigator. I just need this 'AboutScreen' there to use
onPress={() => this.props.navigation.navigate('AboutScreen')}
on another screen called SettingScreen.js. When i use that function above with the AboutScreen instanced in Navigator.js the navigation works but 'AboutScreen' appears in the bottom tab, that's what i don't want. Is there a way to hide only this page 'AboutScreen' that appears in my bottom tab? My codes below:
//This is Navigator.js
const Tab = createBottomTabNavigator({
Home: {screen: HomeScreen,
navigationOptions: {
tabBarLabel: 'Home',
tabBarIcon: ({tintColor, activeTintColor}) => (
<Icon name="home" size={19} color={tintColor} />
)
},},
Catalog: {screen: CatalogScreen,
navigationOptions: {
tabBarLabel: 'Catalog',
tabBarIcon: ({tintColor, activeTintColor}) => (
<Icon name="local-library" size={19} color={tintColor} />
)
},},
MyLibrary: {screen: MyLibraryScreen,
navigationOptions: {
tabBarLabel: 'My Library',
tabBarIcon: ({tintColor, activeTintColor}) => (
<Icon name="star" size={19} color={tintColor} />
)
},},
Setting: {screen: SettingScreen,
navigationOptions: {
tabBarLabel: 'Setting',
tabBarIcon: ({tintColor, activeTintColor}) => (
<Icon name="settings" size={19} color={tintColor} />
)
},},
AboutScreen: {screen: AboutScreen,
navigationOptions: {
tabBarLabel: 'AboutScreen',
tabBarIcon: ({tintColor, activeTintColor}) => (
<Icon name="home" size={19} color={tintColor} />
)
},},
},{
tabBarPosition: 'bottom',
swipeEnabled: true,
showIcon: true,
tabBarOptions:{
showIcon: true,
showLabel: true,
activeTintColor: '#FEFEFE',
inactiveTintColor: '#614B70',
activeBackgroundColor: '#614B70',
inactiveBackgroundColor: '#FEFEFE',
}
});
//And this is the SettingScreen.js where i want to use the 'AboutScreen'
import React from 'react';
import { Platform, StatusBar, StyleSheet, View, Text, TouchableOpacity, ScrollView, Button, Image, TouchableHighlight } from 'react-native';
import { Icon } from 'react-native-elements';
export default class SettingScreen extends React.Component {
render() {
return(
<ScrollView style={styles.container}>
<TouchableOpacity style={styles.itemContainerTouchable}
onPress={() => this.navigateScreen('Home')}>
<View style={styles.itemContainer}>
<Icon
name="settings"
color={'#614B70'}
style={styles.itemIcon}
/>
<Text style={styles.itemText}>General</Text>
</View>
<View
style={{height: 1, width: '100%', backgroundColor: '#614B70'}}
/>
</TouchableOpacity>
</ScrollView>
);
}
navigateScreen(object) {
this.props.navigation.navigate(object);
}
}
//styles are irrelevant
You have to create a customBottomTabNavigator.
The one I'm using right now is this:
import React from 'react'
import { BottomTabBar } from 'react-navigation-tabs'
import { View, TouchableWithoutFeedback, Dimensions } from 'react-native'
import { StyleSheet } from 'react-native';
var { height } = Dimensions.get("window")
const HiddenView = () => <View style={{ display: 'none' }} />
const TouchableWithoutFeedbackWrapper = ({
onPress,
onLongPress,
testID,
accessibilityLabel,
...props
}) => {
return (
<TouchableWithoutFeedback
onPress={onPress}
onLongPress={onLongPress}
testID={testID}
hitSlop={{
left: 15,
right: 15,
top: 5,
bottom: 5,
}}
accessibilityLabel={accessibilityLabel}
>
<View {...props} />
</TouchableWithoutFeedback>
)
}
export default TabBarComponent = props => {
return <BottomTabBar
{...props}
style={styles.bottomBarStyle}
getButtonComponent={({ route }) => {
if (route.key === "ScreenToHideKey" )
return HiddenView
else return TouchableWithoutFeedbackWrapper
}}
/>
}
const styles = StyleSheet.create({
bottomBarStyle: {
height: (height * 10.625) / 100 //your header height (10.625 is the %)
}
})
Then where you use your createBottomTabNavigator:
{
tabBarPosition: 'bottom',
swipeEnabled: true,
showIcon: true,
tabBarComponent: (props) => (<BottomBar {...props} ></BottomBar>) //remember to import it
tabBarOptions:{
showIcon: true,
showLabel: true,
activeTintColor: '#FEFEFE',
inactiveTintColor: '#614B70',
activeBackgroundColor: '#614B70',
inactiveBackgroundColor: '#FEFEFE',
}
You can use a StackNavigator nested inside of your BottomTabBarNavigator, in the nested StackNavigator you put the SettingsScreen first and then the AboutScreen. Then you remove from your tab bar the AboutScreen. and everything should work as expected
I did find this question in a few other places, but I'm still unable to resolve the issue with any of the help given. I got most of the code so far from this article -
https://medium.com/#austinhale/building-a-mobile-app-in-10-days-with-react-native-c2a7a524c6b4
Some of the APIs were outdated, but most of them I was able to replace with the new version - One of the APIs i changed that might be notable in regards to this question is stackNavigator -> createStackNavigator
My code is as follows:
Apps.js
import React, { Component } from 'react';
import {
FlatList,
StatusBar,
StyleSheet,
Text,
View
} from 'react-native';
import AppItem from './AppItem';
export default class Apps extends Component {
constructor(props) {
super(props);
this.state = {
apps: [
{
id: 1,
title: 'Good Business',
description: 'Make millions investing in mindtree minds',
thumbnail: 'https://img12.androidappsapk.co/300/f/5/1/com.nse.bse.sharemarketapp.png'
},
{
id: 2,
title: 'Troll WhatsApp SOS ONLY',
description: 'Have a laugh by reading all the comments in the group chat made by your coworkers',
thumbnail: 'http://icons.iconarchive.com/icons/dtafalonso/android-l/256/WhatsApp-icon.png'
}
]
}
}
_renderItem = ({ item }) => (
<AppItem
id={item.id}
title={item.title}
description={item.description}
thumbnail={item.thumbnail}
/>
);
_keyExtractor = (item, index) => item.id.toString();
render() {
return (
<View style={styles.container}>
<StatusBar
barStyle="light-content"
/>
<FlatList
data={this.state.apps}
keyExtractor={this._keyExtractor}
renderItem={this._renderItem}
/>
</View>
);
}
}
const styles = StyleSheet.create({
container: {
flex: 1,
backgroundColor: '#F5FCFF',
}
});
router.js
import React, { Component } from 'react';
import { Dimensions, Platform } from 'react-native';
import { createStackNavigator, createBottomTabNavigator } from 'react-navigation';
import { Icon } from 'react-native-elements';
import Apps from './screens/Apps';
import Gallery from './screens/Gallery';
import Garage from './screens/Garage';
import News from './screens/News';
import Support from './screens/Support';
import ViewApp from './screens/ViewApp';
let screen = Dimensions.get('window');
export const Tabs = createBottomTabNavigator({
'Apps': {
screen: Apps,
navigationOptions: {
tabBarLabel: 'Apps',
tabBarIcon: ({ tintColor }) => <Icon raised name="ios-apps-outline" type="ionicon" size={28} color={tintColor} />
},
},
'News': {
screen: News,
navigationOptions: {
tabBarLabel: 'News',
tabBarIcon: ({ tintColor }) => <Icon raised name="newspaper-o" type="font-awesome" size={28} color={tintColor} />
},
},
'Garage': {
screen: Garage,
navigationOptions: {
tabBarLabel: 'Garage',
tabBarIcon: ({ tintColor }) => <Icon raised name="garage" type="material-community" size={28} color={tintColor} />
},
},
'Gallery': {
screen: Gallery,
navigationOptions: {
tabBarLabel: 'Gallery',
tabBarIcon: ({ tintColor }) => <Icon raised name="picture" type="simple-line-icon" size={28} color={tintColor} />
},
},
'Support': {
screen: Support,
navigationOptions: {
tabBarLabel: 'Support',
tabBarIcon: ({ tintColor }) => <Icon raised name="ios-person-outline" type="ionicon" size={28} color={tintColor} />
},
},
});
export const AppsStack = createStackNavigator({
Apps: {
screen: Apps,
navigationOptions: ({ navigation }) => ({
header: null,
}),
},
ViewApp: {
screen: ViewApp,
navigationOptions: ({ navigation }) => ({
header: null,
tabBarVisible: false,
gesturesEnabled: false
}),
},
});
export const createRootNavigator = () => {
return createStackNavigator(
{
AppsStack: {
screen: AppsStack,
navigationOptions: {
gesturesEnabled: false
}
},
Tabs: {
screen: Tabs,
navigationOptions: {
gesturesEnabled: false
}
}
},
{
headerMode: "none",
mode: "modal"
}
);
};
AppItem.js
import React, { Component } from 'react';
import {
StyleSheet,
TouchableOpacity,
Text,
Image,
View
} from 'react-native';
import { Icon } from 'react-native-elements';
import { ViewApp } from './ViewApp';
export default class AppItem extends Component {
_onViewApp = () => {
let id = this.props.id;
this.props.navigation.navigate('ViewApp', { id: id })
}
render() {
return (
<TouchableOpacity onPress={this._onViewApp}>
<View style={styles.rowContainer}>
<Image source={{ uri: this.props.thumbnail }}
style={styles.thumbnail}
resizeMode="contain" />
<View style={styles.rowText}>
<Text style={styles.title} numberOfLines={2} ellipsizeMode={'tail'}>
{this.props.title}
</Text>
<Text style={styles.description} numberOfLines={2} ellipsizeMode={'tail'}>
{this.props.description}
</Text>
</View>
</View>
</TouchableOpacity>
);
}
}
const styles = StyleSheet.create({
rowContainer: {
flexDirection: 'row',
backgroundColor: '#FFF',
height: 100,
padding: 10,
marginRight: 10,
marginLeft: 10,
marginTop: 15,
borderRadius: 4,
shadowOffset: { width: 1, height: 1, },
shadowColor: '#CCC',
shadowOpacity: 1.0,
shadowRadius: 1
},
title: {
paddingLeft: 10,
paddingTop: 5,
fontSize: 16,
fontWeight: 'bold',
color: '#777'
},
description: {
paddingLeft: 10,
marginTop: 5,
fontSize: 14,
color: '#777'
},
thumbnail: {
flex: 1,
height: undefined,
width: undefined
},
rowText: {
flex: 4,
flexDirection: 'column'
}
});
You can change your onPress functionality in AppItem.js like below. Use arrow function inside your onPress onPress={() => this._onViewApp()}. Because Arrow function does not create the context "this". It refers to the context of the component that it was wrapped in. For lexical this refer this Arrow function vs function declaration / expressions: Are they equivalent / exchangeable?
import { Icon } from 'react-native-elements';
import { ViewApp } from './ViewApp';
export default class AppItem extends Component {
_onViewApp(){
let id = this.props.id;
this.props.navigation.navigate('ViewApp', { id: id })
}
render() {
return (
<TouchableOpacity onPress={() => this._onViewApp()}>
<View style={styles.rowContainer}>
<Image source={{ uri: this.props.thumbnail }}
style={styles.thumbnail}
resizeMode="contain" />
<View style={styles.rowText}>
<Text style={styles.title} numberOfLines={2} ellipsizeMode={'tail'}>
{this.props.title}
</Text>
<Text style={styles.description} numberOfLines={2} ellipsizeMode={'tail'}>
{this.props.description}
</Text>
</View>
</View>
</TouchableOpacity>
);
}
}
I wanted to follow up for everyone who's having the same issue. I just included withNavigation from 'react-native-navigation'; and exported at the end of the component like so export default withNavigation(AppItem);.
I am trying to navigate from login screen to Tabs screen, But I am getting the following error
Undefined is not an object (evaluating
'this.props.navigation.navigate')
Below is my Login.js:
import React, {Component} from 'react';
import {Text, View, StyleSheet, ImageBackground, Image, TextInput} from 'react-native';
import { Button } from 'react-native-elements'
import firebase from 'firebase';
const textInputConfig = {
placeholderTextColor : '#838383',
}
export default class Login extends Component<{}>{
static navigationOptions = {
header: null
}
login() {
this.props.navigation.navigate('Tabs');
}
render (){
return (
<View style={styles.container}>
<ImageBackground source={require('../resources/images/background_image.png')} style={styles.backgroundImage} >
<Image source={require('../resources/images/app_logo.png')} style={styles.logo}/>
<View style={styles.formContainer}>
<TextInput style={styles.textInput} placeholder='Username'
placeholderTextColor={textInputConfig.placeholderTextColor} autoCapitalize='none'/>
<TextInput style={styles.textInput} placeholder='Email'
placeholderTextColor={textInputConfig.placeholderTextColor} autoCapitalize='none'/>
<TextInput style={styles.textInput} placeholder='Password'
secureTextEntry={true} placeholderTextColor={textInputConfig.placeholderTextColor} autoCapitalize='none'/>
<Button raised title='SIGN UP' buttonStyle={styles.signupButton}
containerViewStyle={styles.signupButtonContainer} onPress={() => this.login()} />
</View>
</ImageBackground>
</View>
);
}
}
.....
Below is my Router.js
import React from 'react';
import { TabNavigator, StackNavigator } from 'react-navigation';
import { Icon } from 'react-native-elements';
import Home from '../screens/Home';
import MyCards from '../screens/MyCards';
import AddCard from '../screens/AddCard';
import Login from '../screens/Login.js';
export const MainScreenNavigator = TabNavigator({
Home: {
screen: Home,
navigationOptions : {
tabBarLabel: 'Home',
tabBarIcon: ({ tintColor }) => <Icon name="account-circle" size={35} color={tintColor} />
},
},
MyCards: {
screen: MyCards,
navigationOptions : {
tabBarLabel: 'My Cards',
tabBarIcon: ({ tintColor }) => <Icon name="list" size={35} color={tintColor} />
},
},
},
{
tabBarPosition: 'bottom',
animationEnabled: true,
tabBarOptions: {
activeTintColor: '#e91e63',
},
},
);
export const AppNavigation = StackNavigator({
LoginScreen: { screen: Login },
Tabs: { screen: MainScreenNavigator},
AddCard: { screen: AddCard }
},
{
headerMode: 'screen'
});
Can someone please tell what I am doing wrong?
Edit Login.js:
import React, {Component} from 'react';
import {Text, View, StyleSheet, ImageBackground, Image, TextInput} from 'react-native';
import { Button } from 'react-native-elements'
import firebase from 'firebase';
const textInputConfig = {
placeholderTextColor : '#838383',
}
export default class Login extends Component<{}>{
static navigationOptions = {
header: null
}
login = () => {
console.log("login function");
this.props.navigation.navigate('Tabs');
}
render (){
return (
<View style={styles.container}>
<ImageBackground source={require('../resources/images/background_image.png')} style={styles.backgroundImage} >
<Image source={require('../resources/images/app_logo.png')} style={styles.logo}/>
<View style={styles.formContainer}>
<TextInput style={styles.textInput} placeholder='Username'
placeholderTextColor={textInputConfig.placeholderTextColor} autoCapitalize='none'/>
<TextInput style={styles.textInput} placeholder='Email'
placeholderTextColor={textInputConfig.placeholderTextColor} autoCapitalize='none'/>
<TextInput style={styles.textInput} placeholder='Password'
secureTextEntry={true} placeholderTextColor={textInputConfig.placeholderTextColor} autoCapitalize='none'/>
<Button raised title='SIGN UP' buttonStyle={styles.signupButton}
containerViewStyle={styles.signupButtonContainer} onPress={this.login} />
</View>
</ImageBackground>
</View>
);
}
}
It has the reference issue!
Replace onPress={() => this.login()} with onPress={this.login.bind(this)}
<Button raised title='SIGN UP' buttonStyle={styles.signupButton}
containerViewStyle={styles.signupButtonContainer} onPress={this.login.bind(this)} />