【问题标题】:Type Error: Undefined is not an object (evaluating this.props.navigation.navigate)类型错误:未定义不是对象(评估 this.props.navigation.navigate)
【发布时间】:2020-04-02 03:13:30
【问题描述】:

所以我正在创建一个支持登录的新登录屏幕,即 Oauth。我从之前制作的通用登录屏幕中添加了一些代码,但我的导航道具收到类型错误。有人可以解释为什么会发生这种情况以及如何解决吗?由于此错误,我的应用程序甚至无法加载,即使错误在 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: {
      }
    });

【问题讨论】:

  • 所以你既没有安装 react-navigation 也没有用 createAppContainer 包装你的 LoginScreen。为了让 navigation.navigate 工作,你需要用 createAppContainer 包裹你的屏幕
  • 我已经安装了 react-navigation 但没有任何工作。
  • 这看起来不错。您能否分享您的路线或 App.js 代码 createAppContainer 所在的位置。
  • 能否添加rootstack.js文件???

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


【解决方案1】:

在您的 App.js 中

&lt;LoginScreen navigation = {this.props.navigation}/&gt;

在您的loginScreen.js &lt;TouchableOpacity onPress={ () =&gt;this.onSubmit()}&gt;

还有,

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

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

这将解决问题:)

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

【讨论】:

  • 添加这个并没有改变我的错误。我的模拟器仍然显示相同的错误。我编辑了我的帖子以展示我当前的登录屏幕和应用 .js 文件。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2018-05-08
  • 1970-01-01
  • 2023-03-14
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多