开发者问题收集

如何修复“无法读取未定义的属性‘navigate’”

2019-07-16
1871

我对 React Native 还很陌生,现在我正在尝试构建一个登录组件,一旦登录成功,我想将组件从登录屏幕重定向到主屏幕。我正在使用 React Navigation,不知何故它一直显示错误“无法读取未定义的属性‘navigate’”。

我做错了什么还是我错过了什么?非常感谢任何帮助!

我正在使用 Visual Studio Code-Insiders (v1.37.0) npm -v:6.4.1 expo -V:2.21.2 react-navigation: ^3.11.0

代码非常简单:

import React, { Component } from 'react';
import { StyleSheet, Text, View } from 'react-native';
import { Avatar, Button, Icon } from 'react-native-elements'
import * as t from 'tcomb-form-native'
import Router from '../config/router';

const Form = t.form.Form;
const PWD = '2';
const UME = 'J';

class Login extends Component {

constructor(props) {
    super(props);

    this.state = {
        login: {}
    };

    this.LoginModel = t.struct({
        un: t.String,
        pwd: t.String,
        rm: t.Boolean
    });

    this.LoginOptions = {
        fields: {
            un: {
                label: 'User Name',
                error: 'Please type your username'
            },
            pwd: {
                label: 'Password',
                password: true,
                secureTextEntry: true,
                error: 'Please type the password'
            },
            rm: {
                label: 'Remember me'
            }
        }
    }

}

onChange(form) {
    this.state.login = form;
}

onSubmit() {

    console.log(this.props); // will output an empty object! but how?

    const { navigate } = this.props.navigation; // Here is where the error message captured and throw out!

    const value = this.refs.form.getValue(); 

    if (value.un === UME && value.pwd === PWD) {
        alert('Welcome back, Jack');
        // setTimeout(() => {
        //     navigate('Home');
        // }, 300);
    }
}

render() {
    return (
        <View style={styles.container}>

            <View style={{ alignItems: "center", marginBottom: 30 }}>
                <Avatar
                    size="xlarge"
                    icon={{ name: 'apple', color: 'black', type: 'font-awesome' }}
                    overlayContainerStyle={{ backgroundColor: 'white' }}
                    onPress={() => console.log("Works!")}
                    activeOpacity={0.7}
                    containerStyle={{ marginTop: 15 }}
                />
            </View>

            <Form
                ref="form"
                type={this.LoginModel}
                value={this.state.login}
                options={this.LoginOptions}
                onChange={(f) => this.onChange(f)}
            />

            <Button
                icon={
                    <Icon
                        type='font-awesome'
                        name="user"
                        size={25}
                        color="white"
                        iconStyle={styles.icon}
                    />
                }
                title="Login"
                style={styles.btn}
                onPress={()=>this.onSubmit()}
            />

        </View>
    );
}
}

const styles = StyleSheet.create({
container: {
    flex: 1,
    padding: 80
},
icon: {
    paddingRight: 10
},
btn: {

}
});

export default Login;

更新: 这是 App.js

import React from 'react';
import { StyleSheet, Text, View } from 'react-native';
import LoginScreen from './src/screens/Login'

export default function App() {
  return (
    <LoginScreen />
 );
}
3个回答

根据您的代码,您尚未创建导航堆栈,只需为您的 Login 组件添加一个 StackNavigator 即可工作

// Other imports
import { createStackNavigator, createAppContainer } from "react-navigation";

...

class Login extends Component {
 ....
}

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

const AppNavigator = createStackNavigator({
  Login: {
    screen: Login
  }
});

export default createAppContainer(AppNavigator);

您可以参考 react-navigation 的文档

但是,这只是一种快速的方法,您可能需要在单独的文件中构建导航堆栈。

Ewe Tek Min
2019-07-17

使用箭头函数可能会奏效:

onSubmit = () => {
  console.log(this.props);
  const { navigate } = this.props.navigation;
//...
}

关键字“this”指的是调用它的函数。但 onSubmit 没有 props。 “ES5 引入了 bind() 方法来设置函数 this 的值,而不管它是如何调用的,而 ES2015 引入了不提供自己的 this 绑定的箭头函数(它保留了封闭词法上下文的 this 值)。”您可以在 https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/this

始终优先使用箭头函数来避免这种情况。:)

Marcelo Monteiro
2019-07-17

从代码中,我假设您正在 App.js 中呈现 LoginScreen。 这样做,您不会将 LoginScreen 放在任何导航器中,从而使 this.props.navigation 等于 undefined

Auticcat
2019-07-17