Cannot read property 'navigation' of undefined Evaluating App.js Loading App.js - react-native

Looking to have button enter go into another screen:
need help with navigation screen.
I keep getting error:
Cannot read property 'navigation' of undefined
Evaluating App.js
Loading App.js
TypeError: Cannot read property 'navigation' of undefined
https://snack.expo.io/#ganiyat1/colorful-thrills
import * as React from 'react';
import { Text, View, StyleSheet, ImageBackground, Image, Button } from 'react-native';
import Constants from 'expo-constants';
import { StackNavigator} from 'react-navigation';
import Books from './components/Books';
// You can import from local files
// or any pure javascript modules available in npm
import { Card } from 'react-native-paper';
const Book = StackNavigator({
Books: { screen: Books },
});
const { navigate } = this.props.navigation;
export default function App() {
return (
<View style={styles.container}>
<View style={styles.topContainer}>
<Text style={styles.title}> Colorful Thrills
</Text >
</View>
<View style={styles.bottomContainer}></View>
<View style={styles.imageContainer}>
<Image
style={styles.image}
source={require('./assets/bookcover.png')}
/>
<Text style={styles.paragraph}>
{"\n"} BOOKWORMS, UNITE! {"\n"} {"\n"}
Suspense, Mystery and Thrillers by Authors of Color
</Text>
<Button
color='#ff914d'
title= 'ENTER'
onPress={() =>
navigate('Books')}
/>
</View>
</View>
);
}

In the above code snippet, I don't see a default Navigator being returned form the entry file, which is App.js by default in React Native.
I assume that you just started to learn React Native, so I will spare you all the minor details and walk you through the solution.
I refactored the App.js file to a into a new component file in /components/Home.js.
Added a default stack Navigator in App.js which has two screens, Home and Books.
Now you can access all the Navigation props in your Home and Books component, as it is being declared in the Navigator variable in App.js
Here is a live demo of your code on Expo.
//App.js
import * as React from 'react';
import { Text, View, StyleSheet, ImageBackground, Image, Button } from 'react-native';
import Constants from 'expo-constants';
import { StackNavigator} from 'react-navigation';
import Books from './components/Books';
import Home from './components/Home'
import { Card } from 'react-native-paper';
const Navigator = StackNavigator({
Books: { screen: Books },
Home:{screen:Home}
});
export default function App(props) {
return (
<Navigator />
);
}
//component/Books.js
import React, { useState } from 'react';
import { StyleSheet, SafeAreaView,Button } from 'react-native';
import MaterialTabs from 'react-native-material-tabs';
const Books = (props) => {
const {navigation} = props
const [selectedTab, setSelectedTab] = useState(0);
return (
<SafeAreaView style={styles.container}>
<MaterialTabs
items={['New Releases', 'All', 'BOM']}
selectedIndex={selectedTab}
onChange={setSelectedTab}
barColor="#1fbcd2"
indicatorColor="#ff914d"
activeTextColor="white"
/>
<Button
color='#ff914d'
title= 'Home'
onPress={() =>
navigation.navigate('Home')}
/>
</SafeAreaView>
);
};
const styles = StyleSheet.create({
container: {
flex: 1,
},
});
export default Books
//component/Home.js
import React from 'react'
import {View,Text,StyleSheet,Button,Image} from 'react-native'
const Home = (props) => {
const {navigation} = props
return (
<View style={styles.container}>
<View style={styles.topContainer}>
<Text style={styles.title}> Colorful Thrills
</Text >
</View>
<View style={styles.bottomContainer}></View>
<View style={styles.imageContainer}>
<Image
style={styles.image}
source={require('../assets/bookcover.png')}
/>
<Text style={styles.paragraph}>
{"\n"} BOOKWORMS, UNITE! {"\n"} {"\n"}
Suspense, Mystery and Thrillers by Authors of Color
</Text>
<Button
color='#ff914d'
title= 'ENTER'
onPress={() =>
navigation.navigate('Books')}
/>
</View>
</View>
)
}
export default Home
const styles = StyleSheet.create({
container: {
flex: 1,
flexDirection: 'column',
},
topContainer: {
flex: 1,
backgroundColor: '#ff914d',
},
bottomContainer: {
flex: 1,
backgroundColor: '#96d0e3',
},
imageContainer: {
position: 'absolute',
width: '100%',
height: '100%',
justifyContent: 'center',
alignItems: 'center',
},
image: {
width: 300,
},
title:{
margin: 24,
marginTop: 50,
fontSize: 40,
fontWeight: 'bold',
textAlign: 'center',
fontFamily: 'GillSans-Italic',
},
paragraph: {
margin: 24,
marginTop: 0,
fontSize: 20,
fontWeight: 'bold',
textAlign: 'center',
}
});

Related

items doesnt stick to bottom react nativr

im trying to make a to-do list in react native and im trying to make the input and plus bar stick to the bottom and make it go up when i open the keyboard. when i use padding the bar sticks to bottom but i want to use flexbox to make it compatible with all phones. can someone help make stick it to bottom and make it go up with keyboard
task.js
import React from 'react';
import {View, Text, SafeAreaView, StyleSheet, TextInput,KeyboardAvoidingView, TouchableWithoutFeedback, TouchableOpacity} from 'react-native';
const AddTask = () => {
const handleAddTask = () => {
Keyboard.dismiss();
setTaskItems([...taskItems, task])
setTask(null);
}
return (
<KeyboardAvoidingView
behavior={Platform.OS === "ios" ? "padding" : "height"}
style ={styles.inputbuttons}
>
<TextInput style={styles.input} placeholder={'Write a task'} />
<TouchableOpacity onPress={() => handleAddTask()}>
<View style = {styles.plus}>
<Text>+</Text>
</View>
</TouchableOpacity>
</KeyboardAvoidingView>
);
};
const styles = StyleSheet.create({
input: {
height: 60,
width:320,
margin: 12,
borderWidth: 1,
padding: 10,
borderRadius:20,
},
inputbuttons:{
flexDirection:'row',
alignItems:'center',
justifyContent:'flex-end'
},
plus:{
width:60,
height:60,
borderWidth:1,
borderColor:'black',
textAlign:'right',
borderRadius:'15',
textAlign: 'center',
justifyContent: 'center',
fontSize:30
}
});
export default AddTask;
app.js
import { StatusBar } from 'expo-status-bar';
import { StyleSheet, Text, View,Button, Alert,Input } from 'react-native';
import Task from './components/Task';
import AddTask from './components/AddTask';
export default function App() {
return (
<View style={styles.container}>
<View style = {styles.taskWrapper}>
<Text style={styles.header}>Today's Tasks</Text>
</View>
<View style={styles.tasks}>
<Task></Task>
<Task></Task>
</View>
<View>
<AddTask></AddTask>
</View>
</View>
);
}
const styles = StyleSheet.create({
container: {
flex: 1,
backgroundColor: '#E8EAED',
},
taskWrapper:{
paddingTop:80,
paddingHorizontal:20
},
header:{
fontSize:24,
fontWeight:'bold'
},
tasks:{
},
});
You should use KeyboardAvoidingView in your app component so that whenever keyboard gets activated then the component of App gets pushed.

Error : 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 got this error when trying to import and use another component that I have created in another file. And I got an error like this :
Error: 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.
Check the render method of `Sidebar`.
This is my code to export component as default component in customDrawer.js which file is same directory:
const Sidebar = ({ isDarkTheme, setIsDarkTheme, ...props }) => {
const handlePress = () => {
props.navigation.dispatch(DrawerActions.closeDrawer());
props.navigation.navigate("Settings");
};
const { colors } = useTheme();
const toggleTheme = () => {
setIsDarkTheme();
};
// console.log('navi--?',props.navigation);
return (
<Container style={{ backgroundColor: colors.background }}>
<Header
style={{
backgroundColor: colors.background,
borderBottomWidth: 0,
marginTop: 70,
borderWidth: 0,
}}
>
<StatusBar barStyle="dark-content" backgroundColor="#ffffff" />
<Right>
<Button transparent>
<TouchableOpacity onPress={() => handlePress()}>
{/* <Ionicons name="ios-options" size={28} color={colors.icon} /> */}
</TouchableOpacity>
</Button>
</Right>
</Header>
<Content>
<DrawerContentScrollView {...props}>
<DrawerItemList {...props} />
</DrawerContentScrollView>
<TouchableOpacity>
<View
style={{
display: "flex",
flexDirection: "row",
alignItems: "center",
paddingRight: 20,
paddingLeft: 20,
paddingTop: 10,
}}
>
<Text style={{ flex: 1, color: colors.text }}>Dark Theme</Text>
<View>
<Switch onValueChange={toggleTheme} value={isDarkTheme} />
</View>
</View>
</TouchableOpacity>
</Content>
</Container>
);
};
const styles = StyleSheet.create({});
export default Sidebar;
And then, in my App.js I have import components like this :
import Sidebar from "./customDrawer";
All imports I use in customDrawer.js :
import {
DrawerContentScrollView,
DrawerItemList,
} from "#react-navigation/drawer";
import { Button, Container, Content, Header, Right } from "native-base";
import React, { useState } from "react";
//import { Ionicons } from "#expo/vector-icons";
import { StyleSheet, Text, View, Switch } from "react-native";
import { StatusBar } from "react-native";
import { TouchableOpacity } from "react-native";
import { DrawerActions } from "#react-navigation/native";
import { useTheme } from "#react-navigation/native";

Unable to navigate using reusable card components in React Native

I have this HomeScreen file, in it I have added Card component(Dashboard & Highlights), I have Customized the Card Components with the TitleCard to reuse the styling,
In each card there is "View All" Button to navigate to its individual Screens,
When I don't use the Cards and put the entire code in home screen and Click on the View All Button on home screen then it navigates to that page, but when I use the Cards and use its props to navigate to the link provided as forwardLink props then
I get this error
"ReferenceError: Can't find variable: navigation"
Also when I add this.props.navigation.navigate('{props.forwardLink}') in TitleCard
I get this error message:
TypeError: undefined is not an object (evaluating '_this.props.navigation')
Here are the codes for each file
TitleCards
import React from 'react';
import {StyleSheet, Text, View, TouchableOpacity} from 'react-native';
const TitleCards = props => {
return (<View style={styles.textTitlesContainer}>
<Text style={styles.textTitle}>{props.leftTitle}</Text>
<TouchableOpacity
onPress={() => navigation.navigate('{props.forwardLink}')}>
<Text style={[styles.textTitle, {color: '#F483A7'}]}>
{props.rightTitle}
</Text>
</TouchableOpacity>
</View>)
};
const styles = StyleSheet.create({
textTitlesContainer: {
flex: 1,
width: '100%',
flexDirection: 'row',
justifyContent: 'space-between',
padding: 5,
},
textTitle: {
fontSize: 20,
fontWeight: '800',
color: '#fff',
},
});
export default TitleCards;
HomeScreen
import React, {Component} from 'react';
import {
SafeAreaView,
ScrollView,
StyleSheet,
} from 'react-native';
import {CustomHeader} from '../index';
import Colors from '../constants/Colors';
import DashboardCard from './DashboardCard';
import HighlightCard from './HighlightCard';
export class HomeScreen extends Component {
render() {
return (
<SafeAreaView style={{flex: 0, backgroundColor: Colors.primary}}>
<CustomHeader
title="Home"
isHome={true}
navigation={this.props.navigation}
/>
<ScrollView style={styles.container}>
<DashboardCard />
<HighlightCard />
</ScrollView>
</SafeAreaView>
);
}
}
const styles = StyleSheet.create({
container: {
height:900, backgroundColor: Colors.mainBackground,
paddingTop:6,
},
});
export default HomeScreen;
HighlightCard
import React, {Component} from 'react';
import {Text, View} from 'react-native';
import {CustomHeader} from '../../index';
const HighlightCard = (prop) => {
return (
<Card>
<TitleCards leftTitle="Highlights" rightTitle="View More" forwardLink="Highlights">
</TitleCards>
<View>
<Text>News Feed</Text>
</View>
</Card>
);
};
export default HighlightCard;
const styles = StyleSheet.create({
textTitle: {
fontSize: 20,
fontWeight: '800',
color: '#fff',
},
});
When I use the HighlightCard codes directly in HomeScreen then it navigates to that page, below is that code which works if I use it directly in Home Screen
*{/* <Text style={styles.textTitle}>Highlights</Text>
<TouchableOpacity
onPress={() => this.props.navigation.navigate('Highlights')}>
<Text style={[styles.textTitle, {color: '#F483A7'}]}>View All</Text>
</TouchableOpacity> */}*
I think there is something wrong I am doing is using the props or referencing to the navigation page
I also tried creating a const for navigation
const {navigate} = this.props.navigation
this didn't worked either

How do i navigate between screens in my shopping app?

'm new to react-native and mobile application. I'm trying to build a basic shopping app.i have the sports options such as cricket,football,tennis and whenever the cricket button is pressed, the cricket products must be displayed and i can follow it up for the other two products
i tried using stack navigator to navigate between screens but i seem to get a error . i tried using createstacknavigator but it doesnt come out right
1.App.js
import React, { Component } from 'react';
import { Text, View } from 'react-native';
import { StackNavigator } from 'react-navigation'
import FirstScreen from './src/FirstScreen'
import SecondScreen from './src/cricket'
const Navigation = StackNavigator({
First: {screen: FirstScreen},
Second: {screen: SecondScreen}
});
export default Navigation
AppRegistry.registerComponent('AwesomeProject', () => Navigation);
2.FirstScreen.js
import React, { Component } from 'react';
import { Alert, AppRegistry, Image, Platform, StyleSheet, Text,
TouchableHighlight, TouchableOpacity, TouchableNativeFeedback,
TouchableWithoutFeedback, View } from 'react-native';
import { StackNavigator } from 'react-navigation'
export default class FirstScreen extends Component {
//_onPressButton() {
// Alert.alert('You tapped the button!')
//}
//_onLongPressButton() {
//Alert.alert('You long-pressed the button!')
//}
static navigationOptions = {
title: 'First Screen',
};
render() {
return (
<View style={styles.container}>
<TouchableOpacity onPress={this._onPressButton}>
<View style={styles.button}>
<Text style={styles.buttonText}>Cricket</Text>
</View>
</TouchableOpacity>
<TouchableOpacity onPress={this._onPressButton}>
<View style={styles.button}>
<Text style={styles.buttonText}>Football</Text>
</View>
</TouchableOpacity>
<TouchableOpacity onPress={this._onPressButton}>
<View style={styles.button}>
<Text style={styles.buttonText}>Tennis</Text>
</View>
</TouchableOpacity>
</View>
);
}
}
const styles = StyleSheet.create({
container: {
paddingTop: 60,
alignItems: 'center'
},
button: {
marginBottom: 30,
width: 260,
alignItems: 'center',
backgroundColor: '#2196F3'
},
buttonText: {
padding: 20,
color: 'white'
}
});
// skip this line if using Create React Native App
//AppRegistry.registerComponent('AwesomeProject', () => Touchables);
3.Cricket.js
import React, { Component } from 'react';
import {Alert, Button, ScrollView, StyleSheet, AppRegistry, Text, View
} from 'react-native';
const styles = StyleSheet.create({
rowContainer: {
flex: 1,
height: 75,
width: '100%',
flexDirection: 'row', // children will be on the same line
justifyContent: 'space-between',
alignItems: 'center',
margin: 10,
},
buttonContainer: {
flex: 1,
},
text: {
flex: 2, // Text takes twice more space as button container
color: 'red',
fontWeight: 'bold',
fontSize: 20,
},
});
class Greeting extends Component {
static navigationOptions = {
title: 'Second Screen',
};
_onPressButton() {
Alert.alert('Sorry you have no credit!')
}
render() {
return (
<View style={styles.rowContainer}>
<Text style={styles.text}>{this.props.name}</Text>
<View style={styles.buttonContainer}>
<Button
onPress={this._onPressButton}
title="BUY"
/>
</View>
</View>
);
}
}
export default class SecondScreen extends Component {
render() {
return (
<ScrollView>
<View style={{alignItems: 'flex-start', top: 0, flex: 2,
backgroundColor: 'black'}}>
<Greeting name='Shoe- 800' />
<Greeting name='Jersey - 350' />
<Greeting name='Stockings - 100' />
<Greeting name='Cones - 50' />
<Greeting name='Whistle - 80' />
<Greeting name='Helmet - 750' />
<Greeting name='Tennis Ball-6 pack - 800' />
<Greeting name='Nets - 1500' />
<Greeting name='Leg Pads - 1000' />
<Greeting name='Stumps - 800' />
<Greeting name='Gloves - 600' />
</View>
</ScrollView>
);
}
}
When the cricket button is pressed, the screen should navigate to the list of cricketproducts which is the (cricket.js)
As you are using react-navigation, you just need to use the navigation prop. You have commented the part where you handle the press. Just change that function to actually navigate to the screen you want:
_onPressButton=()=>{
this.props.navigation.navigate("Second")
}
If you are not using arrow functions, you need to bind the function to have access to the this of that screen. To do that you need to add inside your constructor:
constructor(props){
super(props)
this._onPressButton.bind(this)
}
after that you can call it by doing:
_onPressButton() {
this.props.navigation.navigate("Second")
}
As you are using a stackNavigator, you have different ways to navigate to the other screen of the same stack. You have different ways to navigate. For example:
this.props.navigation.push("Second")
This method pushes a new screen to the stack, no matter what screen it is
this.props.navigation.navigate("Second")
Navigates to a new screen in the stack, will push it in the stack only if the screen hasn't been focussed before
this.props.navigation.replace("Second")
This will navigate to a new screen without pushing it to the stack, "replacing" the screen you was watching with the new one.
EDIT.
For the error you stated in the comment, it's because there's not an app container. To do so, just do:
import { createStackNavigator, createAppContainer } from 'react-navigation'
Then do
const Navigation = createAppContainer(createStackNavigator({
First: {screen: FirstScreen},
Second: {screen: SecondScreen}
}));
Use the Move Screen command.
this.props.navigation.navigate("Second")

this.props.navigation undefined is not an object

I am new in react native. I am using React navigation. But navigation is not working, giving an error:-
"props.navigation undefined is
not an object"
I am giving my project structure and code.
Project Structure:-
Code in App.js:-
import { createStackNavigator, createDrawerNavigator } from 'react-navigation';
import HomeLayout from './src/components/Home/Layout';
import SideMenuLayout from './src/components/DrawerMenu/SideMenu';
import { DetailsScreen } from './DetailsScreen';
const myDrawer = createDrawerNavigator({
Home:{
screen: HomeLayout
},
Details:{
screen: DetailsScreen
},
},{
contentComponent: SideMenuLayout,
drawerWidth: 876/3
})
const native = createStackNavigator({
Home:{
screen: myDrawer,
},
},{
headerMode: 'none',
})
export default native;
SideMenu.js(Layout for drawer navigator). In this section All menus has been rendered.-
import React, {Component} from 'react';
import { View, StyleSheet} from 'react-native';
import DrawerHeader from './DrawerHeader';
import DrawerMenu from './DrawerMenu';
class SideMenuLayout extends Component {
state = {
menuNames:[{
id:'0',
name:'My Profile'
},{
id:'1',
name:'Place Order'
},{
id:'2',
name:'Order History'
},{
id:'3',
name:'Payment'
},{
id:'4',
name:'Recharge'
},{
id:'5',
name:'Help'
},{
id:'6',
name:'Logout'
}]
}
render () {
return (
<View style={styles.container} >
<DrawerHeader/>
<DrawerMenu menuItems={this.state} style={{ marginTop: 106/3}}/>
</View>
);
}
}
export default SideMenuLayout;
const styles = StyleSheet.create({
container:{
flex:1,
backgroundColor: "#ffffff",
}
});
Drawer Menu.js. In this section all menus are rendered and want to navigate from here.
import React, {Component} from 'react';
import {FlatList, Text, View, StyleSheet,TouchableOpacity} from 'react-native';
import Dash from 'react-native-dash';
import { FontAwesome } from '#expo/vector-icons';
import { StackNavigator } from 'react-navigation';
const DrawerMenu = (props)=>{
const { navigate } = props.navigation;
return (
<View style={styles.menuContainer}>
<FlatList
data={props.menuItems.menuNames}
renderItem={(info) => (
<View>
<View
style={{
width:690/3,
backgroundColor: '#ffffff',
height:141/3,
paddingTop:48/3,
flexDirection:'row',
marginBottom:7
}}>
<View style={{position:"relative",width:390/3,height:'100%',backgroundColor:'#ffffff',alignSelf: 'flex-start'}}>
<TouchableOpacity onPress={()=>navigate('Details')}>
<Text style={{color:'#615b5b',fontSize:18,fontFamily:'sans-serif'}}>
{info.item.name}
</Text>
</TouchableOpacity>
</View>
<View
style={{
alignItems:"center",
justifyContent:'center',
position:"relative",
width:300/3,
backgroundColor:'#ffffff',
paddingRight:10,
paddingBottom:5,
}}>
<FontAwesome
style={{ alignSelf: 'flex-end'}}
name="angle-right"
size={18}
color="#615b5b"
/>
</View>
</View>
<Dash dashColor = '#d6d6d6' style={{width:'100%', height:1,alignSelf: 'flex-start'}}/>
</View>
)}
keyExtractor={(info, index) => info.id}
/>
</View>
);
}
export default DrawerMenu;
const styles = StyleSheet.create({
menuContainer:{
width: 700/3,
height:1425/3,
alignSelf: 'flex-end',
backgroundColor: '#ffffff',
paddingTop: 61/3,
}
});
The SideMenuLayout has a navigation prop passed to it automatically by the Drawer. So you need to pass that further to your DrawerMenu
<DrawerMenu navigation={this.props.navigation} menuItems={this.state} style={{ marginTop: 106/3}}/>
...
export default SideMenuLayout;
SideMenuLayout.propTypes = {
navigation: PropTypes.object // Or use flow, or it does not really matter. It's just type validation.
}
And the you can use navigate in your DrawerMenu like you use it now.