undefined is not an object (evaluating _this2.props.navigation.navigate)

4.6k views Asked by At

I'm working with react-native and I'm facing a problem with navigators.

The code:

App.js

import React, {Component} from 'react';
import {
   AppRegistry,
   StyleSheet,
   Text,
   View,
} from 'react-native';

import { StackNavigator } from 'react-navigation';

import loginScreen from './src/components/loginView';
import registerScreen from './src/components/registerView';

const Appmemes = StackNavigator({
   Login: {screen: loginScreen},
   Register: {screen: registerScreen}
});

export default Appmemes;

AppRegistry.registerComponent('Appmemes', () => Appmemes);

loginView.js works correctly:

.
.
.
  <View style={styles.formContainer}>
          <LoginForm/>
  </View>
.
.
.    

LoginForm.js

import React, { Component } from 'react'
import { StyleSheet, TextInput, Text, View, TouchableOpacity, AppRegistry} from 'react-native'
import { StackNavigator} from 'react-navigation';

export default class LoginForm extends Component{
  render() {
      return(
      <View style={styles.container}>

          <TouchableOpacity style={styles.buttonContainer1}>
            <Text style={styles.buttonText}>Entrar</Text>
          </TouchableOpacity>

          <TouchableOpacity style={styles.buttonContainer2} onPress={() => this.props.navigation.navigate('Login')}>

            <Text style={styles.buttonText}>Registrarse</Text>
          </TouchableOpacity>
      </View>
    );
  }
}

AppRegistry.registerComponent('LoginForm', () => LoginForm);

const styles = StyleSheet.create({...]);
});

The error is:

undefined is not an object (evaluating _this2.props.navigation.navigate)

The error is in OnPress() in LoginForm.js

onPress={() => this.props.navigation.navigate('Login')

What could be the cause for this error?

1

There are 1 answers

6
Mustansir Zia On BEST ANSWER

Simply. <LoginForm navigation={this.props.navigation} />

The error is occurring because the LoginFrom isn't getting loaded directly using the StackNavigator and only those components that are directly loaded by the StackNavigator get the navigation prop (like loginScreen in your case). Any nested components inside loginScreen won't receive the navigation prop automatically so we need to pass it explicitly to LoginForm since it will get passed to loginScreen.

I've answered a similar question here.

Sidenote: I believe you're navigating from inside loginScreen to loginScreen again using this.props.navigation.navigate('Login') as LoginForm is inside loginScreen itself. So in this case you probably mean to navigate to Register. So you should write this.props.navigation.navigate('Register').

Plus, you also don't need AppRegistry.registerComponent('LoginForm', () => LoginForm); This is because you only need to register one root component with AppRegistry. So, Appmemes should only be registered with AppRegistry which you're already doing. LoginForm will automatically get mounted by loginScreen which will, in turn, get mounted by Appmemes.