Stack navigator giving me undefined error

I'm using https://facebook.github.io/react-native/docs/navigation.html by the way.

I'm trying to use the StackNavigator to go from Login.js to AboutDendro.js. What's wrong in my <Button/> component that's throwing that error in my iOS simulator?

enter image description here

Here's Login.js:

import React, { Component } from 'react';
import { connect } from 'react-redux';
import { ScrollView, Text, TextInput, View, Button, StyleSheet } from 'react-native';
import { login } from '../redux/actions/auth';
import {AuthenticationDetails, CognitoUser, CognitoUserAttribute, CognitoUserPool} from '../lib/aws-cognito-identity';
import StackNavigator from 'react-navigation';
import AboutDendro from './AboutDendro';

const awsCognitoSettings = {
    UserPoolId: 'something',
    ClientId: 'something'
};

class Login extends Component {
    constructor (props) {
        super(props);
        this.state = {
            page: 'Login',
            username: '',
            password: ''
        };
    }

    get alt () { return (this.state.page === 'Login') ? 'SignUp' : 'Login'; }

    handleClick (e) {
        e.preventDefault();
        const userPool = new CognitoUserPool(awsCognitoSettings);

        // Sign up
        if (this.state.page === 'SignUp') {
            const attributeList = [
                new CognitoUserAttribute({ Name: 'email', Value: this.state.username })
            ];
            userPool.signUp(
                this.state.username,
                this.state.password,
                attributeList,
                null,
                (err, result) => {
                    if (err) {
                        alert(err);
                        this.setState({ username: '', password: '' });
                        return;
                    }
                    console.log(`result = ${JSON.stringify(result)}`);
                    this.props.onLogin(this.state.username, this.state.password);
                }
            );
        } else {
            const authDetails = new AuthenticationDetails({
                Username: this.state.username,
                Password: this.state.password
            });
            const cognitoUser = new CognitoUser({
                Username: this.state.username,
                Pool: userPool
            });
            cognitoUser.authenticateUser(authDetails, {
                onSuccess: (result) => {
                    console.log(`access token = ${result.getAccessToken().getJwtToken()}`);
                    this.props.onLogin(this.state.username, this.state.password);
                },
                onFailure: (err) => {
                    alert(err);
                    this.setState({ username: '', password: '' });
                    return;
                }
            });
        }
    }

    togglePage (e) {
        this.setState({ page: this.alt });
        e.preventDefault();
    }

    static navigationOptions = {
        title: 'AboutDendro',
    };

    render() {
        const { navigate } = this.props.navigation;
        const App = StackNavigator({
            Home: { screen: Login },
            Profile: { screen: AboutDendro },
        });

        return (
            <ScrollView style={{padding: 20}}>
                <Button
                    title="Go to Jane's profile"
                    onPress={() =>
                        navigate('AboutDendro', { name: 'AboutDendro' })
                    }
                />
                <Text style={{fontSize: 27}}>{this.state.page}</Text>
                <TextInput
                    placeholder='Email Address'
                    autoCapitalize='none'
                    autoCorrect={false}
                    autoFocus={true}
                    keyboardType='email-address'
                    value={this.state.username}
                    onChangeText={(text) => this.setState({ username: text })} />
                <TextInput
                    placeholder='Password'
                    autoCapitalize='none'
                    autoCorrect={false}
                    secureTextEntry={true}
                    value={this.state.password}
                    onChangeText={(text) => this.setState({ password: text })} />
                <View style={{margin: 7}}/>
                <Button onPress={(e) => this.handleClick(e)} title={this.state.page}/>
                <View style={styles.firstView}>
                    <Text onPress={(e) => this.togglePage(e)} style={styles.buttons}>
                        {this.alt}
                    </Text>
                </View>
            </ScrollView>
        );
    }
}

const styles = StyleSheet.create({
    buttons: {
        fontSize: 12,
        color: 'blue',
        flex: 1
    },

    firstView: {
        margin: 7,
        flexDirection: 'row',
        justifyContent: 'center'
    }
});

const mapStateToProps = (state, ownProps) => {
    return {
        isLoggedIn: state.auth.isLoggedIn
    };
}

const mapDispatchToProps = (dispatch) => {
    return {
        onLogin: (username, password) => { dispatch(login(username, password)); }
    }
}

export default connect(mapStateToProps, mapDispatchToProps)(Login);

Answers:

Answer

It is because navigation is not in your props. It is a part of your App component you created. But you do nothing with this component.

You should have an App.js file, with your stackNavigator, set your Login component as your default component in your stackNavigator's parameters.

Take a look at this documentation

Answer

I try to refactor your code. in component render maybe you can just write :

render() {
    const { navigate } = this.props.navigation;
    return (
        <ScrollView style={{padding: 20}}>
            <Button
                title="Go to Jane's profile"
                onPress={() =>
                    navigate('Profile', { name: 'AboutDendro' })
                }
            />
            <Text style={{fontSize: 27}}>{this.state.page}</Text>
            <TextInput
                placeholder='Email Address'
                autoCapitalize='none'
                autoCorrect={false}
                autoFocus={true}
                keyboardType='email-address'
                value={this.state.username}
                onChangeText={(text) => this.setState({ username: text })} />
            <TextInput
                placeholder='Password'
                autoCapitalize='none'
                autoCorrect={false}
                secureTextEntry={true}
                value={this.state.password}
                onChangeText={(text) => this.setState({ password: text })} />
            <View style={{margin: 7}}/>
            <Button onPress={(e) => this.handleClick(e)} title={this.state.page}/>
            <View style={styles.firstView}>
                <Text onPress={(e) => this.togglePage(e)} style={styles.buttons}>
                    {this.alt}
                </Text>
            </View>
        </ScrollView>
    );
  }
}

And you separate component StackNavigation below component render() like:

 const App = StackNavigator({
        Home: { screen: Login },
        Profile: { screen: AboutDendro },
    });

And then import component App in your index.ios.js like:

import './Login';

just that. Maybe my answer can help you.

Tags

Recent Questions

Top Questions

Home Tags Terms of Service Privacy Policy DMCA Contact Us Javascript

©2020 All rights reserved.