react-native navigation in Flatlist component over multiple files - react-native

I am using react-navigation for navigation and right now i am trying to navigate between Screens using my flatlist. I want it so that when i click on an item in the list that i get send to the Details screen, but whenever i press on an item in the list with this code, nothing happens. I tried to pass the navigation property from the Homescreen component to the MyListItem Component but then i get undefined is not an Object error.
However, i have a Test TouchableOpacity in my Homescreen Component and if i click on that, i can navigate to the Details screen (See "Test" Text in Homescreen Component).
I think i did something wrong with the navigation property, but i have been searching everywhere and have not found a solution.
This is my App.js file with the StackNavigator:
import React from 'react';
import { createStackNavigator } from 'react-navigation'
import HomeScreen from './screens/HomeScreen'
import DetailScreen from './screens/DetailScreen'
const RootStack = createStackNavigator(
{
Home: HomeScreen,
Details: DetailScreen,
},
{
initialRouteName: 'Home',
navigationOptions: {
header: null,
},
}
);
export default class App extends React.Component {
render() {
return <RootStack />;
}
}
This is my HomeScreen file where the Problem is happening:
import React from 'react'
import { StyleSheet, Text, View, TouchableOpacity, StatusBar,
FlatList, Image } from 'react-native'
import Data from '../data/Data'
class MyListItem extends React.Component {
render() {
return(
<View style={styles.container}>
<TouchableOpacity
onPress={this.props.handleOnPress}
>
<View style={{ flexDirection: 'row', heigth: 100, width: 100 }}>
<View>
<Image style={{ height: 50, width: 50, resizeMode: 'contain' }} source={require('../res/icon.png')} />
</View>
<View style={{ justifyContent: 'center' }}>
<Text>
{this.props.item.name}
</Text>
</View>
</View>
</TouchableOpacity>
</View>
);
}
}
class HomeScreen extends React.Component {
handleOnPress = () => {
this.props.navigation.navigate('Details')
}
render() {
return (
<View>
<StatusBar hidden={true} />
<TouchableOpacity
onPress={() => this.props.navigation.navigate('Details')}
>
<Text>Test</Text>
</TouchableOpacity>
<FlatList
data={Data}
renderItem={({ item }) =>
<MyListItem
item={item}
onPress={this.handleOnPress}
/>
}
/>
</View>
);
}
}
export default HomeScreen;
Ps: I run the Code on an Android emulator.
Edit: edited answer suggestion into code

Might be a typo mistake but, you try to navigate to navigate('Details') when you declared your screen as Detail
{
Home: HomeScreen,
Detail: DetailScreen, <----
},

Related

React native navigation: '_this2.props.navigation.navigate'

my App.js code
import React from 'react'
import { Icon } from 'react-native-elements'
import { StyleSheet, View, StatusBar } from 'react-native'
import { createAppContainer } from 'react-navigation'
import { createStackNavigator } from 'react-navigation-stack'
import HomeScreen from './screens/homeScreen'
import LoginScreen from './screens/loginScreen'
import SignupScreen from './screens/signup'
import Screen2 from './screens/screen2'
import Screen1 from './screens/screen1'
export default class App extends React.Component {
setLogged(){
this.setState({logged:true})
this.forceUpdate()
}
//change to false when want to enable login feature else true
state = {
logged: false,
}
render() {
if(this.state.logged){
return(
<View style={styles.container} >
<StatusBar hidden = {false}/>
<AppContainer />
</View>
)
}else{
return(
<View style={styles.container} >
<StatusBar hidden = {false}/>
<LoginScreen signup={()=>this.props.navigation.navigate('Signup')} success={()=>this.setLogged()} />
</View>
)
}
}
}
const styles = StyleSheet.create({
container: {
position: 'relative',
width: '100%',
height: '100%',
backgroundColor: '#000000',
},
})
const HomeAppContainer = createStackNavigator(
{
Home: {screen: HomeScreen},
Signup: { screen: SignupScreen },
Screen1: { screen: Screen1 },
Screen2: { screen: Screen2 },
},
{initialRouteName: "Home"},
);
const AppContainer = createAppContainer(HomeAppContainer)
and the login screen contains
import React, { Component } from 'react';
import { StyleSheet, View, Text, TouchableOpacity, TextInput, ToastAndroid } from 'react-native';
import Colors from '../constants/colors'
import GLOBAL from '../constants/global'
export default class LoginScreen extends Component {
state = {
email: '',
password: '',
}
login() {
if (userid == 'admin') {
ToastAndroid.show('Invalid email/password', ToastAndroid.SHORT);
} else {
GLOBAL.userid = userid;
this.props.success()
}
})
}
render() {
return (
<View style={styles.MainContainer}>
<Text style={styles.text}>Email:</Text>
<View style={styles.inputView}>
<TextInput
style={styles.inputs}
autoFocus
returnKeyType="next"
keyboardType="email-address"
onChangeText={(email) => { this.setState({ email: email }) }}
/>
</View>
<Text style={styles.text}>Password:</Text>
<View style={styles.inputView}>
<TextInput
style={styles.inputs}
secureTextEntry
onChangeText={(password) => { this.setState({password:password}) }}
/>
</View>
<View style={styles.buttonGroup}>
<TouchableOpacity
style={styles.button}
onPress={() => { this.login() }} >
<Text style={{ fontSize: 24 }}>Sign in</Text>
</TouchableOpacity>
<TouchableOpacity
style={styles.button}
onPress={() => { this.props.signup() }}>
<Text style={{ fontSize:24 }}>Sign up</Text>
</TouchableOpacity>
</View>
</View>
);
}
}
const styles = StyleSheet.create({
//my styles here
});
the error is as follows
TypeError: undefined is not an object(evaluating '_this2.props.navigation.navigate')
i am learning react-native and making this login screen.
The app will check if the user is already logged in. if not then he will be prompted login screen which will have sign up option.
If the user is already logged in the app will directly go to home screen where screen1 and screen2 is used in stack
Well, the navigation prop is only passed down the navigation tree. Your App component is not a navigation screen like Home/Signup... (it doesn't have a route)... So basically App is not part of a navigator, it's not created using createStackNavigator or the others.
So, in conclusion the navigation prop is not defined.
Basically, how to fix this: LoginScreen should also be a route inside a navigator, therefore the navigation prop will be defined. Your App component should not render anything besides the <AppContainer /> and further logic should be handled in the first screen defined in the routes, which in your case might be the LoginScreen. In there you'll check if the user is logged in or not and navigate accordingly.
There's a great guide on their website on how to accomplish authentication flow: https://reactnavigation.org/docs/en/4.x/auth-flow.html

Why custom functions execute automatically in react-native-navigation drawer component during screen render

I am new to react-native. I am using react-native-navigation (by wix) for navigating. I have created "Drawerscreen" component for drawer sidebar, under component class I have created a function with name of "navigateToScr". Here "navigateToScr" function calls automatically during initialize component without calling from anywhere, please anyone can explain me why this happening?
import React, {Component} from 'react';
import {Text, View, StyleSheet, TouchableOpacity, ScrollView, SafeAreaView } from 'react-native'
export default class Drawerscreen extends Component {
constructor (props){
super(props);
}
navigateToScr = () =>{
console.log('in');
}
render() {
return (
<View style={styles.container}>
<ScrollView>
<SafeAreaView style={styles.container} forceInset={{ top: 'always', horizontal: 'never' }}>
<TouchableOpacity onPress={this.navigateToScr()} style={styles.menulinkcon}>
<Text style={styles.menulink}>Test 1</Text>
</TouchableOpacity>
<TouchableOpacity onPress={this.navigateToScr()} style={styles.menulinkcon}>
<Text style={styles.menulink}>Test 2</Text>
</TouchableOpacity>
</SafeAreaView>
</ScrollView>
</View>
)
}
}
const styles = StyleSheet.create({ ... });
``````````````````````````````````````````````````````````````````````
````````````````````````````````````````````````````````````````
Navigation.startSingleScreenApp({
screen: {
screen: "screen.MainScreen",
title: 'Main Screen',
},
drawer: {
left: {
screen: 'screen.Drawerscreen',
fixedWidth: 500
}
}
});
````````````````````````````````````````````````````````````````
By putting open & close parenthesis after this.navigateToScr, you're actually calling it and setting onPress to its returned value. If you only want to run the function when it is pressed, instead use
onPress={this.navigateToScr}
or
onPress={() => this.navigateToScr()}
The latter is often used when you need to pass a value into the method.

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

I am having trouble navigating through screens with a simple button.
This is my App.js
export default class App extends Component<Props> {
render() {
return (
<AppStackNavigator/>
);
}
}
const AppStackNavigator = StackNavigator({
Login: { screen: LoginScreen },
Home: { screen: HomeScreen },
},{
navigationOptions: {
gesturesEnabled:false
}
})
Login.js
export default 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}>
<Image style={styles.logo}
source={require('../images/logo/logo.png')}>
</Image>
<Text style={styles.title}>
Sports Chat App
</Text>
</View>
<View style={styles.infoContainer}>
<TextInput style={styles.input}
placeholder="Enter name"
placeholderTextColor='#ffffff'
keyboardType='default'
returnKeyType='next'
autoCorrect={false}
onSubmitEditing={()=> this.refs.phoneNumber.focus()}
/>
<TextInput style={styles.input}
placeholder="Enter phone number"
placeholderTextColor='#ffffff'
keyboardType='phone-pad'
ref={'phoneNumber'}
/>
<TouchableOpacity style={styles.buttonContainer}>
<Button title='LogIn' onPress={()=>this.props.navigation.navigate('Home')}/>
</TouchableOpacity>
</View>
</View>
</TouchableWithoutFeedback>
</KeyboardAvoidingView>
</SafeAreaView>
)
}
};
LoginScreen.js
class LoginScreen extends Component {
render(){
return (
<View>
<Login>
</Login>
</View>
);
}
}
I keep getting the error undefined is not an object (evaluating'_this2.props.navigation.navigate') whenever i try use the Login button in Login.js,
I want this to navigate to the home screen but cant figure out why this keeps happening.
If i try do it without the components it works fine.
Click to View error message
Add a navigation props to Login in LoginScreen.js, Because LoginScreen has props navigation but Login don't.
render(){
return (
<View>
<Login navigation ={this.props.navigation}>
</Login>
</View>
);
}
App.js
import React, { Component } from "react";
import { Text, View } from "react-native";
import AppStackNavigator from "./AppStackNavigator";
export default class App extends Component<Props> {
render() {
return <AppStackNavigator />;
}
}
AppStackNavigator
import React, { Component } from "react";
import { StackNavigator } from "react-navigation";
import { View, Text, TouchableOpacity } from "react-native";
const LoginScreen = props => (
<View style={{ flex: 1, justifyContent: "center", alignItems: "center" }}>
<Login navigation={props.navigation} />
</View>
);
const HomeScreen = () => (
<View style={{ flex: 1, justifyContent: "center", alignItems: "center" }}>
<Text>Home</Text>
</View>
);
const Login = props => (
<View style={{ flex: 1, justifyContent: "center", alignItems: "center" }}>
<TouchableOpacity
onPress={() => {
props.navigation.navigate("Home");
}}
>
<Text>GO to home from login</Text>
</TouchableOpacity>
</View>
);
export default (AppStackNavigator = StackNavigator(
{
Login: { screen: LoginScreen },
Home: { screen: HomeScreen }
},
{
headerMode: "none",
navigationOptions: {
gesturesEnabled: false
}
}
));
You need to access the navigation prop in the component. Check the official guide.
reactnavigation Official guide
import React from 'react';
import { Button } from 'react-native';
import { withNavigation } from 'react-navigation';
class MyBackButton extends React.Component {
render() {
return <Button title="Back" onPress={() => { this.props.navigation.goBack() }} />;
}
}
// withNavigation returns a component that wraps MyBackButton and passes in the
// navigation prop
export default withNavigation(MyBackButton);

React navigation this.props.navigation undefined

I have a custom header like this
import React from 'react';
import { View, TouchableOpacity, Text, StyleSheet, Image } from 'react-native';
import { Header, Left, Right, } from 'native-base';
import { Icon } from 'react-native-elements';
export default class MainHeader extends React.Component {
pressSearch() {
this.props.navigation.navigate('Login');
}
render () {
return(
<Header style={{paddingTop:25}}>
<Left style={{marginBottom:10}}>
<TouchableOpacity>
<View style={{flexDirection:'row'}}>
<Image
style={styles.stretch}
source={require('../images/logoforplay.png')}
/>
<Text style={styles.headerText} > Eventlinn </Text>
</View>
</TouchableOpacity>
</Left>
<Right>
<TouchableOpacity
style={styles.headerButton}
onPress={this.pressSearch.bind(this)}
>
<Icon
name={'search'}
/>
</TouchableOpacity>
<TouchableOpacity
style={styles.headerButton}
>
<Icon
name={'add-location'}
/>
</TouchableOpacity>
<TouchableOpacity
style={styles.headerButton}
>
<Icon
name={'notifications'}
/>
</TouchableOpacity>
</Right>
</Header>
)
}
}
const styles = StyleSheet.create ({
mainContainer: {
flex:1,
backgroundColor:'white'
},
cardContainer: {
flex:1
},
stretch: {
height:35,
width:35,
},
headerText: {
fontSize:24,
marginTop:3,
},
headerButton: {
marginBottom:10,
marginLeft:15
}
})
My problem navigation.navigate not working.My routers working well because i can navigate to 'login' with another screen.I read something about pure components but still dont understand how to solve this problem.What do you suggest ? By the way i am new to react native.
If your header isn't a route within your Router at the head of your app you will need to use withRouter from react-router
import {withNavigation} from 'react-navigation'
export default withNavigation(MainHeader)
Now you should be able to access this.props.navigation without directly passing it down as a prop from a parent component.
use import { withNavigation } from 'react-navigation'; at the top and then export default withNavigation(FilmItem); at the end.
See doc : https://reactnavigation.org/docs/en/connecting-navigation-prop.html

React Native Drawer navigation

Hi there I am trying to implement a drawer navigation in React Native
referring to this example.
I have almost finished the coding but I am getting an error while adding the contentComponent attribute in drawer class (HomeScreenRouter). After removing it I am able to run it successfully and everything is working well but when I add the sidebar menu using contentComponent it throws an error. I need a custom design for my drawer.
Here is my code for the drawer:
import React, { Component } from "react";
import HomeScreen from "./HomeScreen.js";
import MainScreenNavigator from "../DealScreen/mychat.js";
import Profiled from "../profilescreen/Profile.js";
import SideBar from "../SideBar/SideBar.js";
import { DrawerNavigator } from "react-navigation";
const HomeScreenRouter = DrawerNavigator(
{
Home: { screen: HomeScreen },
Chat: { screen: MainScreenNavigator },
Profile: { screen: Profiled },
},
{
contentComponent: props => <SideBar {...props} />
});
export default HomeScreenRouter;
Sidemenu :
import React from "react";
import { AppRegistry, Image, StatusBar } from "react-native";
import { Container, Content, Text, List, ListItem } from "native-base";
export default class SideBar extends React.Component {
render() {
const routes = ["Home", "Chat", "Profile"];
return (
<Container>
<Content>
<Image
source={{
uri: "https://github.com/GeekyAnts/NativeBase-KitchenSink/raw/react-navigation/img/drawer-cover.png"
}}
style={{
height: 120,
alignSelf: "stretch",
justifyContent: "center",
alignItems: "center"
}}>
<Image
square
style={{ height: 80, width: 70 }}
source={{
uri: "https://github.com/GeekyAnts/NativeBase-KitchenSink/raw/react-navigation/img/logo.png"
}}
/>
</Image>
<List
dataArray={routes}
renderRow={data => {
return (
<ListItem
button
onPress={() => this.props.navigation.navigate("Profile")}>
<Text>{data}</Text>
</ListItem>
);
}}
/>
</Content>
</Container>
);
}
}