android - 使用带有切换屏幕的 StackNavigator 时出错
问题描述
我正在尝试使用 stackNavigator 制作注册/登录屏幕。但是当我尝试从登录页面导航到注册页面时。
我尝试创建一个 const 作为导航属性,但我得到了相同的结果。如果我使用 stackNavigator 在同一个文件中完成所有屏幕,我不会收到错误消息,但这并不是我真正想要做的。
这是我的登录屏幕首先(在进入 index.js 中的这个屏幕之前,我调用 Welcome 类来检查用户是否登录,如果他没有登录,我会返回
export default class Login extends React.Component{
render(){
return(
<ScrollView style={{padding : 20}}>
<Text style={styles.title}>
Login
</Text>
<TextInput style={styles.input} placeholder="Email Address"/>
<TextInput style={styles.input} placeholder="Password" />
<View style={{margin : 7}}/>
<TouchableOpacity
onPress={() => this.props.navigation.navigate('Signup')}
>
<Text> Don't have an account? Click here</Text>
</TouchableOpacity>
<Button
onPress={this.props.onLoginPress}
title="Log in"
color='grey'
/>
</ScrollView>
);
}
}
我的注册屏幕很空,它现在只返回一个带有标题的视图最后这是我的 StackNavigator 文件
const AppNavigator = createStackNavigator({
Welcome: {
screen : Welcome
} ,
Login: {
screen: Login
},
Signup : {
screen : Signup
},
},
{
initialRouteName: "Welcome"
});
export default createAppContainer(AppNavigator);
Welcome 是检查用户是否登录的文件不是
我得到的错误是“错误未定义不是一个对象(评估'_this.props.navigation.navigate')。” 当我单击 Login.js 中的
解决方案
检查你的回购。你的welcome
屏幕首先检查用户是否登录,如果没有登录,它会渲染屏幕login
。您不是在屏幕之间导航,而是呈现另一个登录屏幕。问题就在这里。我举个例子:Welcome
Login
在您的手机(例如 iPhone X)中,您从 App Store 下载并安装了 Facebook。然后您登录了您的帐户。这意味着,您手机中的 Facebook 应用程序现在已配置为使用您的帐户。现在,如果您想发布您的照片,如果您下载并安装另一个 Facebook 应用程序并尝试从那里发布,您将无法做到这一点。您将必须使用配置为使用您的帐户的同一旧应用程序。(实际上您将无法一次下载两个:P)
同样,您应该告诉堆栈导航器导航到堆栈导航器的login
屏幕,而不是渲染另一个login
屏幕。您创建的新login
屏幕将没有导航道具,除非您通过一个。
但还有另一种方式。您可以像渲染signup
屏幕一样渲染login
屏幕。将此代码复制到您的Welcome.js
:
import React from 'react';
import { Text, View, Button } from 'react-native';
import LoginScreen from './LoginScreen';
import SignupScreen from './Signup';
import DrawerNavigator from '../navigation/DrawerNavigator';
const notLoggedIn=0, loggedIn=1, signingUp=2;
export default class Welcome extends React.Component{
constructor(props){
super(props);
this.state={
state: notLoggedIn
}
}
render(){
switch (this.state.state){
case notLoggedIn:
return (
<LoginScreen
onLoginPress={()=>this.setState({state:loggedIn})}
onSignUpPress={()=>this.setState({state:signingUp})}
/>
);
case loggedIn:
return <DrawerNavigator />;
case signingUp:
return <SignupScreen />; //Add onBackPress={()=>this.setState({state:notLoggedIn})}} prop here if you want
}
}
}
然后在你的Login.js
,将 onPress 道具从 更改this.props.navigation.navigate('Signup')
为this.props.onSignUpPress()
。
您现在不需要堆栈导航器。(您现在拥有自己的导航器)因此,您现在可以直接使用您的Welcome
屏幕,而不是使用该堆栈导航器。现在您可以删除 stacknavigator.js 文件。
我想这应该可以解决。
提示:看到您的文件中有许多未使用的样式和导入。如果你真的不打算使用它们,你可以删除这些行。这取决于你。
编辑:
要将函数传递给导航器,您可以使用 screenProps 道具。
编辑您的Welcome.js
:
case loggedIn:
return <DrawerNavigator logout={()=>this.setState({state:notLoggedIn})} />;
DrawerNavigator.js
:
...
const DrawerNavigator = createAppContainer(createDrawerNavigator(
...
));
export default class navigator extends React.Component {
render(){
return <DrawerNavigator screenProps={{logout: this.props.logout}} />
}
}
在你的内部logout.js
,从你想要的任何地方调用函数this.props.screenProps.logout()
。这应该有效。