如何使用 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);
在我的 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);