如何使用 react-native-navigation 在屏幕之间正确导航?

How to properly navigate between screen with react-native-navigation?

在我的 react-native 应用程序中,我有一个登录屏幕和一个主屏幕。 逻辑是:登录过程(使用 Firebase)成功,我们有一个“用户”对象, 我们想从登录屏幕导航到主屏幕。 当我尝试实现它时,身份验证/登录部分工作正常,但“navigation.navigate”部分导致此错误:

“TypeError:undefined 不是对象(正在计算 'navigation.navigate')”。

这是我的 App.js:

import React, { useEffect, useState } from 'react';

import { Navigation } from 'react-native-navigation';

import LoginScreen from './src/screens/LoginScreen/LoginScreen';


import {
  SafeAreaView,
  StyleSheet,
  ScrollView,
  View,
  Text,
  StatusBar,
  Button
} from 'react-native';

import {
  Header,
  LearnMoreLinks,
  Colors,
  DebugInstructions,
  ReloadInstructions,
} from 'react-native/Libraries/NewAppScreen';

const App = (props) => {

  

  return (
    <View style={styles.root}>
    <LoginScreen />
  </View>
  );
};

App.options = {
  topBar: {
    title: {
      text: 'Home',
      color: 'white'
    },
    background: {
      color: '#4d089a' 
    }
  }
}

Navigation.registerComponent('Home', () => App);

Navigation.events().registerAppLaunchedListener(async () => {
  Navigation.setRoot({
    root: {
      stack: {
        children: [
          {
            component: {
              name: 'Home'
            }
          }
        ]
      }
    }
  });
});
const styles = StyleSheet.create({
  root: {
    flex: 1,
    alignItems: 'center',
    justifyContent: 'center',
    backgroundColor: 'whitesmoke'
  }
});

export default App;

这是我的登录屏幕,其中有这个错误诱导部分:

navigation.navigate('Home', {user: user})

:

import React, { useState, useEffect } from 'react'
import { Image, Text, TextInput, TouchableOpacity, View } from 'react-native'
import { KeyboardAwareScrollView } from 'react-native-keyboard-aware-scroll-view';
import styles from './styles';
import { firebase } from '../../firebase/config'
import { NavigationContainer } from '@react-navigation/native';
import { createStackNavigator } from '@react-navigation/stack';

export default function LoginScreen({ navigation }) {
    const [email, setEmail] = useState('')
    const [password, setPassword] = useState('')

    const [loading, setLoading] = useState(true)
    const [user, setUser] = useState(null)

    const Stack = createStackNavigator()
  
    useEffect(() => {
      const usersRef = firebase.firestore().collection('users');
      firebase.auth().onAuthStateChanged(user => {
        if (user) {
          usersRef
            .doc(user.uid)
            .get()
            .then((document) => {
              const userData = document.data()
              setLoading(false)
              setUser(userData)
            })
            .catch((error) => {
              setLoading(false)
            });
        } else {
          setLoading(false)
        }
      });
    }, []);

    const onFooterLinkPress = () => {
        navigation.navigate('Registration')
    }

    const onLoginPress = () => {
        firebase
            .auth()
            .signInWithEmailAndPassword(email, password)
            .then((response) => {
                const uid = response.user.uid
                const usersRef = firebase.firestore().collection('users')
                usersRef
                    .doc(uid)
                    .get()
                    .then(firestoreDocument => {
                        if (!firestoreDocument.exists) {
                            alert("User does not exist anymore.")
                            return;
                        }
                        const user = firestoreDocument.data()
                        navigation.navigate('Home', {user: user})
                    })
                    .catch(error => {
                        alert(error)
                    });
            })
            .catch(error => {
                alert(error)
            })
    }

    return (
        <View style={styles.container}>
            <KeyboardAwareScrollView
                style={{ flex: 1, width: '100%' }}
                keyboardShouldPersistTaps="always">
                <Image
                    style={styles.logo}
                    source={require('../../../assets/icon.png')}
                />
                <TextInput
                    style={styles.input}
                    placeholder='E-mail'
                    placeholderTextColor="#aaaaaa"
                    onChangeText={(text) => setEmail(text)}
                    value={email}
                    underlineColorAndroid="transparent"
                    autoCapitalize="none"
                />
                <TextInput
                    style={styles.input}
                    placeholderTextColor="#aaaaaa"
                    secureTextEntry
                    placeholder='Password'
                    onChangeText={(text) => setPassword(text)}
                    value={password}
                    underlineColorAndroid="transparent"
                    autoCapitalize="none"
                />
                <TouchableOpacity
                    style={styles.button}
                    onPress={() => onLoginPress()}>
                    <Text style={styles.buttonTitle}>Log in</Text>
                </TouchableOpacity>
                <View style={styles.footerView}>
                    <Text style={styles.footerText}>Don't have an account? <Text onPress={onFooterLinkPress} style={styles.footerLink}>Sign up</Text></Text>
                </View>
            </KeyboardAwareScrollView>
        </View>
    )
}

在这种情况下处理导航的正确方法是什么?

根据此 link ,您正在尝试将 App 组件注册为导航容器中的 'Home' 屏幕。我不认为那是你想要的。

Navigation.registerComponent('Home', () => App);

您还需要注册您的主屏幕,否则您将无法导航到它。您的 App 组件将自动注入导航道具,因此您只需将其传递给登录组件即可。尝试以下操作:

const App = (props) => {
  return (
    <View style={styles.root}>
    <LoginScreen ...props/>
  </View>
  );
};

App.options = {
  topBar: {
    title: {
      text: 'Home',
      color: 'white'
    },
    background: {
      color: '#4d089a' 
    }
  }
}

Navigation.registerComponent('Login', () => App);
Navigation.registerComponent('Home', () => YourHomeComponent);