React Native: React-Navigation Cannot read property 'navigate' of undefined - javascript

I am currently learning React Native and was having some issue with React-navigation.
What I am trying to do is switch screen when the "button" is being pressed.
In the "button", I have:
onPress={() =>
navigate('Home')}
I have const { navigate } = this.props.navigation; before the return statement.
When I run it, I am getting "Cannot read property 'navigate' of undefined.
I guess it is I have to place this.props.navigation somewhere.
Here are my two files:
"IntroPageFive" is the one that has the button and "react-navigation".
I would like to go to "IntroPageOne" when the button is being clicked.
Code for "IntroPageFive":
import React from 'react';
import { Text, View, Image, Linking, Button, TouchableOpacity } from 'react-native';
import PlaceholderImage from '../images/placeholder_thumbnail.png';
import SignInFooter from './signInFooter';
import { createStackNavigator } from 'react-navigation';
import IntroPageOne from './introPageOne';
const App = createStackNavigator({
Home: { screen: IntroPageOne },
});
class IntroPageFive extends React.Component {
render() {
const {
headerTextStyle,
thumbnailStyle,
viewStyle,
subTextStyle,
mainTextSection,
footerSectionStyle,
startButtonStyle,
startButtonTextStyle,
signInButtonStyle ,
signInButtonTextStyle
} = styles;
const { navigate } = this.props.navigation;
return (
<View style={viewStyle}>
<Image style={thumbnailStyle} source={require('../images/placeholder_thumbnail.png')} />
<View style={mainTextSection}>
<Text style={headerTextStyle}>Take A Ride For</Text>
<Text style={headerTextStyle}>Your Favorite Car!</Text>
</View>
<View>
<TouchableOpacity
onPress={() =>
navigate('Home')
}
style={startButtonStyle}
>
<Text style={startButtonTextStyle}>LET'S GET STARTED</Text>
</TouchableOpacity>
</View>
<View style={footerSectionStyle}>
<SignInFooter />
</View>
</View>
);
}
}
export default IntroPageFive;
Here is the code for "IntroPageOne":
import React from 'react';
import { Text, View, Image, Linking } from 'react-native';
import PlaceholderImage from '../images/placeholder_thumbnail.png';
import SignInFooter from './signInFooter';
const IntroPageOne = () => {
const { headerTextStyle, thumbnailStyle, viewStyle, subTextStyle } = styles;
return (
<View style={viewStyle} >
<Image style={thumbnailStyle} source={require('../images/placeholder_thumbnail.png')} />
<Text style={headerTextStyle}>Forget Everything You</Text>
<Text style={headerTextStyle}>Know About Making</Text>
<Text style={headerTextStyle}>Deals For Your Car</Text>
<Text style={subTextStyle}>Deal negotiation powered by AI</Text>
<SignInFooter />
</View>
);
};
};
export default IntroPageOne;
Could anyone please tell me how to fix this issue?
Thank you.

Related

Application Breaks when adding custom component as import

I am having an issue where I have created two components "TaskInputField.js" and "TaskItem.js" and when I import them into the file I want to use them in, the browser window I am viewing the app on turns completely blank (using expo). Can post screenshots of what I mean if needed.
This has never happened to me before where simply importing a file breaks the application.
If I remove the imports from GroceryList.js and remove where I use them in the file, everything else runs just fine. I followed a guide for most of this also so I am unsure what is happening.
Thanks in advance.
For reference:
TaskInputField.js
import React, {useState} from 'react';
import { KeyboardAvoidingView, StyleSheet, View, TextInput, TouchableOpacity, } from "react-native";
import { MaterialIcons } from '#expo/vector-icons';
export default TaskInputField = (props) => {
const [task, setTask] = useState();
const handleAddTask = (value) => {
props.addTask(value);
setTask(null);
}
return (
<KeyboardAvoidingView
behavior={Platform.OS === "ios" ? "padding" : "height"}
style={styles.container}
>
<TextInput style={styles.inputField} value={task} onChangeText={text => setTask(text)} placeholder={'Write a task'} placeholderTextColor={'#fff'}/>
<TouchableOpacity onPress={() => handleAddTask(task)}>
<View style={styles.button}>
<MaterialIcons name="keyboard-arrow-up" size={24} color="black" />
</View>
</TouchableOpacity>
</KeyboardAvoidingView>
);
}
TaskItem.js
import React from 'react';
import { StyleSheet, Text, View, TouchableOpacity, } from "react-native";
import { MaterialIcons } from '#expo/vector-icons';
export default TaskItem = (props) => {
return (
<View style={styles.container}>
<View style={styles.indexContainer}>
<Text style={styles.index}>{props.index}</Text>
</View>
<View style={styles.taskContainer}>
<Text style={styles.task}>{props.task}</Text>
<TouchableOpacity onPress={() => props.deleteTask()}>
<MaterialIcons style={styles.delete} name="delete" size={18} color='#fff' />
</TouchableOpacity>
</View>
</View>
);
}
I am implementing these here in GroceryList.js
import React, {useState} from 'react';
import { Keyboard, ScrollView, StyleSheet, Text, View } from 'react-native';
import TaskInputField from '../../components/TaskInputField';
import TaskItem from '../../components/TaskItem';
export default function GroceryList() {
const [tasks, setTasks] = useState([]);
const addTask = (task) => {
if (task == null) return;
setTasks([...tasks, task]);
Keyboard.dismiss();
}
const deleteTask = (deleteIndex) => {
setTasks(tasks.filter((value, index) => index != deleteIndex));
}
return(
<View style={styles.container}>
<Text style={styles.heading}>Grocery List</Text>
<ScrollView style={styles.scrollView}>
{
tasks.map((task, index) => {
return (
<View key={index} style={styles.taskContainer}>
<TaskItem index={index + 1} task={task} deleteTask={() => deleteTask(index)}/>
</View>
);
})
}
</ScrollView>
<TaskInputField addTask={addTask}/>
</View>
)
}

React Native: undefined is not an object (evaluating 'props.navigation.navigate')

I'm learning React Native and by trying to run this code using Expo it gives me the Exception error:
undefined is not an object (evaluating 'props.navigation.navigate'), at line 17 on App.js (marked in the comment)
There are two files: App.js and Untitled1.js
App:
import { StyleSheet, Text, View, TextInput, TouchableOpacity } from 'react-native';
import 'react-native-gesture-handler';
import { NavigationContainer } from '#react-navigation/native';
function App(props) {
return (
<View style={styles.container}>
<Text style={styles.logo}>APPetito</Text>
<Text style={styles.loginText}>Welcome to our app!</Text>
<Text style={styles.loginText}>Choose what do you want to do</Text>
// [ THE FOLLOWING LINE CONTAINS THE ERROR ]
<TouchableOpacity onPress={() => props.navigation.navigate("Untitled1")} style={styles.loginBtn}>
<Text style={styles.loginText}>I eat food</Text>
</TouchableOpacity>
<TouchableOpacity style={styles.loginBtn}>
<Text style={styles.loginText}>I sell food</Text>
</TouchableOpacity>
</View>
);
}
// here there are the const styles
export default App;
Untitled.js
import * as React from 'react';
import React, { Component } from "react";
import { StyleSheet, View, Text } from "react-native";
import Icon from "react-native-vector-icons/Entypo";
import { NavigationContainer } from '#react-navigation/native';
function Untitled1(props) {
return (
<View style={styles.container}>
<Icon name="check" style={styles.icon}></Icon>
<Text style={styles.itWorks}>It works!</Text>
</View>
);
}
// here there are the const styles
export default Untitled1;
What can I do to solve the problem?
I think the problem is that you didn't create a Stack navigator in the first place to navigate between screens. Refer to react navigation docs to know more here
According to the docs you have to implement the stack navigator such as:
import * as React from 'react';
import { NavigationContainer } from '#react-navigation/native';
import { createStackNavigator } from '#react-navigation/stack';
function Home(props) {
return (
<View style={styles.container}>
<Text style={styles.logo}>APPetito</Text>
<Text style={styles.loginText}>Welcome to our app!</Text>
<Text style={styles.loginText}>Choose what do you want to do</Text>
<TouchableOpacity onPress={() => props.navigation.navigate("Untitled1")} style={styles.loginBtn}>
<Text style={styles.loginText}>I eat food</Text>
</TouchableOpacity>
<TouchableOpacity style={styles.loginBtn}>
<Text style={styles.loginText}>I sell food</Text>
</TouchableOpacity>
</View>
);
}
const Stack = createStackNavigator();
function App() {
return (
<NavigationContainer>
<Stack.Navigator>
<Stack.Screen name="Home" component={Home} />
<Stack.Screen name="Untitled1" component={Untitled1} />
</Stack.Navigator>
</NavigationContainer>
);
}
export default App;
I have updated your code a little bit to help you understand the concept.

Expo react native Element type is invalid: expected a string or a class/function but got: undefined

I try to learn react-native sorry if this is a dump question.
I created an demo app with expo init using managed flow. And try to add carousel in home screen by using react-native-sideswipe.
I found an example snack and tried to add it in my app. But I am getting this error for Carousel component in HomeScreen.js :
Invariant Violation: Invariant Violation: Element type is invalid: expected a string (for built-in components) or a class/function (for composite components) but got: undefined. You likely forgot to export your component from the file it's defined in, or you might have mixed up default and named imports.
I can't figure out what is the problem and how can I solve this. I check the components and props are exists in the version which I am using.
Related part of App.js:
const [isLoadingComplete, setLoadingComplete] = useState(false);
if (!isLoadingComplete && !props.skipLoadingScreen) {
return (
<AppLoading
startAsync={loadResourcesAsync}
onError={handleLoadingError}
onFinish={() => handleFinishLoading(setLoadingComplete)}
/>
);
} else {
return (
<View style={styles.container}>
{Platform.OS === 'ios' && <StatusBar barStyle="default" />}
<AppNavigator />
</View>
);
}
}
Related part of AppNavigator.js
import React from 'react';
import { createAppContainer, createSwitchNavigator } from 'react-navigation';
import MainTabNavigator from './MainTabNavigator';
export default createAppContainer(
createSwitchNavigator({
// You could add another route here for authentication.
// Read more at https://reactnavigation.org/docs/en/auth-flow.html
Main: MainTabNavigator,
})
);
Related part of MainTabNavigator.js
import React from 'react';
import { Platform } from 'react-native';
import { createStackNavigator, createBottomTabNavigator } from 'react-navigation';
import HomeScreen from '../screens/HomeScreen';
const config = Platform.select({
web: { headerMode: 'screen' },
default: {},
});
const HomeStack = createStackNavigator(
{
Home: HomeScreen,
},
config
);
HomesSreen.js:
import React from 'react';
import {
Animated,
Easing,
Image,
Platform,
ScrollView,
StyleSheet,
Text,
TouchableOpacity,
View,
Dimensions,
} from 'react-native';
import { Constants } from 'expo';
import { MonoText } from '../components/StyledText';
import { Carousel, AnimatedCarouselItem } from 'react-native-sideswipe';
import { Card, Badge } from 'react-native-elements';
const { width } = Dimensions.get('window');
const data = [1, 2, 3, 4, 5];
export default function HomeScreen() {
return (
<View style={styles.container}>
<ScrollView
style={styles.container}
contentContainerStyle={styles.contentContainer}>
<View style={styles.welcomeContainer}>
<Image
source={require('../assets/images/logo.png')}
style={styles.headerImage}
/>
<Carousel
data={data}
style={{ width, maxHeight: 225 }}
itemWidth={width}
threshold={120}
contentOffset={0}
renderItem={({ item }) => (
<View style={{ width: width, paddingHorizontal: 10 }}>
<Card
title="Local Modules"
containerStyle={{ maxWidth: width, height: 225 }}>
<Badge value={item} />
<Text style={{ marginTop: 10 }}>
Science
</Text>
</Card>
</View>
)}
/>
</View>
<View style={styles.helpContainer}>
</View>
</ScrollView>
<View style={styles.tabBarInfoContainer}>
</View>
</View>
);
}
Thanks for your help!
I think you need to export HomeStack from MainTabNavigator.js:
export default const HomeStack = createStackNavigator({
Home: HomeScreen,
},
config
);
Let me know if that doesn't work.

How to go from one screen to another in react native expo project?

I have created an application using React native expo where I have two screens - Splash & Login. So, after the Splash screen appears for 3 seconds it goes to the Login Screen. Now, in the Login Screen I just want to perform a single task - by clicking the Sign in button I want to switch the login Screen back to the Splash Screen.
Below I have provided the code of my three classes-
App.js
import React from 'react';
import { StyleSheet, Text, View } from 'react-native';
import store from './src/store';
import {Provider} from 'react-redux';
import Splash from './src/Splash';
import Login from './src/Login';
export default class App extends React.Component {
constructor(props) {
super(props);
this.state ={currentScreen:'Splash'};
console.log('Start doing some tasks for about 3 seconds')
setTimeout( ()=> {
console.log('Done some tasks for about 3 second')
this.setState({currentScreen: 'Login'})
} , 3000)
}
render() {
const {currentScreen} = this.state;
let mainScreen = currentScreen === 'Splash' ?
<Splash/> : <Login/>
return mainScreen
}
}
Login.js
import React, {Component} from 'react';
import { StyleSheet, Text, View, Image, TouchableWithoutFeedback,
StatusBar, TextInput, SafeAreaView, Keyboard, TouchableOpacity,
KeyboardAvoidingView } from 'react-native';
class Login extends Component {
render() {
return (
<SafeAreaView style={styles.container}>
<StatusBar barStyle="light-content"/>
<KeyboardAvoidingView
behavior = "padding"
style={styles.container}
>
<TouchableWithoutFeedback
style = {styles.container}
onPress = {Keyboard.dismiss}
>
<View style = {styles.logoContainer}>
<View style = {styles.logoContainer}>
<Text style={styles.title}>
Account Information
</Text>
</View>
<View style={styles.infoContainer}>
<TextInput
style = {styles.input}
placeholder = "Enter User name/Email"
placeholderTextColor = 'rgba(255,255,255,0.8)'
keyboardType = 'email-address'
returnKeyType = 'next'
autoCorrect= {false}
onSubmitEditing = {() => this.refs.txtPassword.focus()}
/>
<TextInput
style = {styles.input}
placeholder = "Enter Password"
placeholderTextColor = 'rgba(255,255,255,0.8)'
returnKeyType = 'go'
autoCorrect= {false}
ref = {"textPassword"}
/>
<TouchableOpacity style={styles.buttonContainer}>
<Text style={styles.buttonText}>SIGN IN</Text>
</TouchableOpacity>
</View>
</View>
</TouchableWithoutFeedback>
</KeyboardAvoidingView>
</SafeAreaView>
);
}
}
export default Login;
Splash.js
import React, {Component} from 'react';
import { StyleSheet, Text, View } from 'react-native';
class Splash extends Component {
render() {
return (
<View style={styles.container}>
<Text style={styles.title}>Hello Splash</Text>
</View>
);
}
}
export default Splash;
Then I just installed the react navigation using the following command-
npm install --save react-navigation
And then followed the React native expo documantation-
https://docs.expo.io/versions/latest/react-native/navigation/
But none of them was working according to the plan. So, I just need one easy solution to go from the Login screen to Splash screen by the Sign In button press. It would be very nice if anyone help me about this.
You can make use of react-navigation for navigating from Splash screen to login and back.
I have made some changes to your code.
App.js
import React from "react";
import { createStackNavigator, createAppContainer } from "react-navigation";
import SplashScreen from "./Splash";
import Login from "./Login";
const AppNavigator = createStackNavigator({
SplashScreen: {
screen: SplashScreen
},
Login: {
screen: Login
}
});
export default createAppContainer(AppNavigator);
Splash.js
import React, { Component } from "react";
import { StyleSheet, Text, View } from "react-native";
class Splash extends Component {
constructor(props) {
super(props);
setTimeout(() => {
props.navigation.navigate("Login");
}, 3000);
}
render() {
return (
<View style={styles.container}>
<Text style={styles.title}>Hello Splash</Text>
</View>
);
}
}
export default Splash;
Login.js
import React, { Component } from "react";
import {
StyleSheet,
Text,
View,
Image,
TouchableWithoutFeedback,
StatusBar,
TextInput,
SafeAreaView,
Keyboard,
TouchableOpacity,
KeyboardAvoidingView
} from "react-native";
class Login extends Component {
render() {
const { navigation } = this.props;
return (
<SafeAreaView style={styles.container}>
<StatusBar barStyle="light-content" />
<KeyboardAvoidingView behavior="padding" style={styles.container}>
<TouchableWithoutFeedback
style={styles.container}
onPress={Keyboard.dismiss}
>
<View style={styles.logoContainer}>
<View style={styles.logoContainer}>
<Text style={styles.title}>Account Information</Text>
</View>
<View style={styles.infoContainer}>
<TextInput
style={styles.input}
placeholder="Enter User name/Email"
placeholderTextColor="rgba(255,255,255,0.8)"
keyboardType="email-address"
returnKeyType="next"
autoCorrect={false}
onSubmitEditing={() => this.refs.txtPassword.focus()}
/>
<TextInput
style={styles.input}
placeholder="Enter Password"
placeholderTextColor="rgba(255,255,255,0.8)"
returnKeyType="go"
autoCorrect={false}
ref={"textPassword"}
/>
<TouchableOpacity style={styles.buttonContainer} onPress={() => navigation.navigate("SplashScreen")}>
<Text style={styles.buttonText}>SIGN IN</Text>
</TouchableOpacity>
</View>
</View>
</TouchableWithoutFeedback>
</KeyboardAvoidingView>
</SafeAreaView>
);
}
}
export default Login;
Also I would suggest reading the docs of react-navigation. The examples given there are simple.
https://reactnavigation.org/docs/en/hello-react-navigation.html
Change the code of App.js. you have already install react navigation.
App.js :
import { StyleSheet, Text, View } from 'react-native';
import {createStackNavigator} from 'react-navigation';
import store from './src/store';
import {Provider} from 'react-redux';
import SplashScreen from './src/Splash';
import LoginScreen from './src/Login';
const App = createStackNavigator({
Splash: { screen: SplashScreen },
Login: { screen: LoginScreen },
});
export default App;
On Login screen sign button onPress :
this.props.navigation.goBack();

How can I use react navigation props in class component?

I have created a Share icon which on click share's pdf or image file on social accounts like facebook, whatsapp, gmail, etc. I want to pass URL link of shareable file inside class component but getting error. If I hardcode the URL then it works fine but how can I pass URL which I receive from react navigation ?
Working code:
import React, { Component } from 'react';
import { Share, View, TouchableOpacity } from 'react-native';
import Icon from 'react-native-vector-icons/Ionicons';
const shareOptions = {
title: 'Download Brochure',
url: 'https://cpbook.propstory.com/upload/project/brochure/5bc58ae6ca1cc858191327.pdf'
}
export default class Screen extends Component {
onSharePress = () => Share.share(shareOptions);
render() {
return (
<View>
<Text style={styles.infoTitle}>Share: </Text>
<TouchableOpacity onPress={this.onSharePress}>
<Icon style={{paddingLeft: 10, paddingTop: 10}}name="md-share" size={30} color="black"/>
</TouchableOpacity>
</View>
}
}
Above code works fine but below code gives error saying shareOptions is undefined. How can I overcome this problem ? I want to pass file URL inside shareOptions. I am getting file url from react navigation props i.e brochure.
Code:
import React, { Component } from 'react';
import { Share, View, TouchableOpacity } from 'react-native';
import Icon from 'react-native-vector-icons/Ionicons';
export default class Screen extends Component {
onSharePress = () => Share.share(shareOptions); <---Getting error here shareOptions undefined
render() {
const project = this.props.navigation.getParam('project', null);
let { brochure } = project;
const shareOptions = {
title: 'Download Brochure',
url: brochure
}
return (
<View>
<Text style={styles.infoTitle}>Share: </Text>
<TouchableOpacity onPress={this.onSharePress}>
<Icon style={{paddingLeft: 10, paddingTop: 10}}name="md-share" size={30} color="black"/>
</TouchableOpacity>
</View>
)
}
How can I overcome above problem and how can I pass props i.e file URL in above case URL is in brochure props.
Just pass shareOptions object to onSharePress function as param and get shareOptions in onSharePress event handler function
import React, { Component } from 'react';
import { Share, View, TouchableOpacity } from 'react-native';
import Icon from 'react-native-vector-icons/Ionicons';
export default class Screen extends Component {
onSharePress = (shareOptions) => {
Share.share(shareOptions);
}
render() {
const { navigation } = this.props;
const project = navigation.getParam('project', null);
const { brochure } = project;
const shareOptions = {
title: 'Download Brochure',
url: brochure
}
return (
<View>
<Text style={styles.infoTitle}>Share: </Text>
<TouchableOpacity onPress={() => this.onSharePress(shareOptions)}>
<Icon style={{paddingLeft: 10, paddingTop: 10}}name="md-share" size={30} color="black"/>
</TouchableOpacity>
</View>
)
}
}
You're not passing shareOptions to your share method, thus it is undefined.
There are many ways you could refactor your code, below you can see a more viable approach.
Since your render function used none of the logic above your return statement, I have simply migrated all of that into the onSharePress function, naturally if these differ, then you would want to pass it in via a parameter.
export default class Screen extends Component {
onSharePress = () => {
const project = this.props.navigation.getParam('project', null);
let { brochure } = project;
const shareOptions = {
title: 'Download Brochure',
url: brochure
}
Share.share(shareOptions);
}
render() {
return (
<View>
<Text style={styles.infoTitle}>Share: </Text>
<TouchableOpacity onPress={this.onSharePress>
<Icon style={{paddingLeft: 10, paddingTop: 10}}name="md-share" size={30} color="black"/>
</TouchableOpacity>
</View>
)
}
}

Categories