类型错误:未定义不是对象(评估this.props.navigation.navigate)

时间:2019-12-09 02:14:48

标签: javascript reactjs react-native react-navigation typeerror

因此,我正在创建一个支持登录的新登录屏幕Oauth。我从之前的通用登录屏幕添加了一些代码,但我的导航道具收到“ Type Error”(输入错误)。有人可以解释为什么会这样以及如何解决吗?由于该错误,即使该错误在APp.js中显示,我的应用程序也无法加载:56.在我的应用程序文件中,我正在使用jsx调用日志屏幕。

LoginScreen.js

import React from 'react';
import {
    View,
    Image,
    Text,
    Dimensions,
    StyleSheet,
    TouchableOpacity,
    Alert,
    Animated,
    Easing,
    TextInput } from 'react-native';
import { AppLoading } from 'expo';
import { Asset } from 'expo-asset';
import { FontAwesome as Icon } from '@expo/vector-icons';
import FBSDK, { LoginManager } from 'react-native-fbsdk';
import { ifIphoneX } from 'react-native-iphone-x-helper';
import firebase from 'firebase';
import { AppAuth } from 'expo';
import Footer from '../Components/Footer';
import * as userActions from '../reducers/user/Actions';
import {
    EMAIL_REGIX, //What is this EMAIL_REGIX?
    EMAIL_ALERT,
    PASSWORD_ALERT,
    PASSWORD_MESSAGE,
    FB_ALERT,
    ACCOUNT,
    FORGOT,
    SIGNUP
} from '../utils/constants';

const { width, height } = Dimensions.get('window');

class LoginScreen extends React.Component {

  onSubmit = () => {
      const {
          navigation: { navigate }
      } = this.props;
      if (!EMAIL_REGIX.test(this.state.email)) {
          Alert.alert('Alert', EMAIL_ALERT);
      } else if (this.state.password.length < 6) {
          Alert.alert('Alert', PASSWORD_ALERT);
      } else if (this.state.password.length > 15) {
          Alert.alert('Alert', PASSWORD_MESSAGE);
      } else {
          navigate(ACCOUNT);
      }
  };

checkIfUserIsLoggedIn = () => {
      firebase.auth().onAuthStateChanged(user => {
          if (user) {
              this.props.navigation.navigate('Account');
          } else {
              this.props.navigation.navigate('LoginScreen');
          }
      });
  };

render() {
  const {
      navigation: { navigate }
  } = this.props;
  return (
      <View style={styles.container}>
        <View style={{ ...StyleSheet.absoluteFill }}>
        <Image
          source={require('../assets/Images/TemplatePic.jpg')}
          style={{ flex: 1, height: null, width: null }}
          resizeMode="cover"
        />
        </View>
        <View style={{ height: height / 3, backgroundColor: 'white' }} />
        <TouchableOpacity onPress={this.onSubmit}>
          <View
            style={[
              styles.loginbutton,
              commonStyles.alignSelfcenter,

              {
                width: width * 0.73
              }
            ]}
          >
            <Text style={[styles.logintextbutton]}>Sign In</Text>
          </View>
        </TouchableOpacity>
      </View>

  );
}
}

const styles = StyleSheet.create({
  container: {
    width: '100%',
    flex: 1,
    backgroundColor: 'red',
    justifyContent: 'flex-end'
  },
  loginbutton: {
    width: 320,
    backgroundColor: 'rgb(72, 244, 255)',
    borderRadius: 20,
    shadowColor: '#000',
    shadowOffset: { width: 0, height: 2 },
    shadowOpacity: 0.5,
    shadowRadius: 5,
    elevation: 20
  },
  logintextbutton: {
    fontSize: 16,
    textAlign: 'center',
    justifyContent: 'center',
    color: 'white',
    fontFamily: 'Helvetica-Bold'
  },
});

export default LoginScreen;

App.js

import React from 'react';
import { View, Image, Dimensions, SafeAreaView, StyleSheet, Text } from 'react-native';
import { Provider, connect } from 'react-redux';
import { AppLoading } from 'expo';
import { Asset } from 'expo-asset';
import * as firebase from 'firebase';
import { firebaseConfig } from './config.js';
import RootStack from './RootStack';
import LoginScreen from './App/screens/LoginScreen';
import configureStore from './App/reducers/configureStore';

firebase.initializeApp(firebaseConfig);
// create store from redux
const store = configureStore();

function cacheImages(images) {
  return images.map(image => {
    if (typeof image === 'string') {
      return Image.prefetch(image);
    }
      return Asset.fromModule(image).downloadAsync();
  });
}

export default class App extends React.Component {
    // Render the app container component with the provider around it
      constructor(props) {
        super(props);
        this.state = {
          isReady: false
        };
      }

      async _loadAssetsAsync() {
        const imageAssets = cacheImages([
          require('./assets/images/TemplatePic.jpg'),
        ]);

        await Promise.all([...imageAssets]);
      }

    render() {
      //If the state is not ready then display the apploading oterwise display the app
      if (!this.state.isReady) {
          return (
            <AppLoading
              startAsync={this._loadAssetsAsync}
              onFinish={() => this.setState({ isReady: true })}
              onError={console.warn}
            />
          );
        }
      return (
        <View style={styles.background}>
          <Provider store={store}>
            <LoginScreen navigation={this.props.navigation} />
          </Provider>
        </View>
      );
    }
    }

    const styles = StyleSheet.create({
      background: {
        flex: 1,
        backgroundColor: '#FFFFFF',
        justifyContent: 'center',
        alignItems: 'center',
        fontSize: 16
      },
      textStyle: {
      }
    });

enter image description here

enter image description here

1 个答案:

答案 0 :(得分:1)

在您的App.js中

<LoginScreen navigation = {this.props.navigation}/>

在您的loginScreen.js<TouchableOpacity onPress={ () =>this.onSubmit()}>

也是

checkIfUserIsLoggedIn = () => {
const that = this;
      firebase.auth().onAuthStateChanged(user => {

          if (user) {
              that.props.navigation.navigate('Account');
          } else {
              that.props.navigation.navigate('LoginScreen');
          }
      });
  };

这将解决问题:)

您需要将导航传递到子组件以使其可访问。