将StackNavigator与切换屏幕一起使用时出错

时间:2019-06-27 18:06:10

标签: android react-native react-navigation

我正在尝试使用stackNavigator创建一个SignUp / Login屏幕。 但是当我尝试从登录页面导航到注册页面时。

我尝试创建一个将是navigation属性的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);

“欢迎使用”是检查用户是否登录的文件

我得到的错误是“未定义错误不是对象(正在评估'_this.props.navigation.navigate')”。当我单击Login.js中的

1 个答案:

答案 0 :(得分:0)

检查了您的仓库。您的welcome屏幕首先检查用户是否已登录,如果未登录,则会显示 login屏幕。您不是Welcome屏幕,而是渲染另一个登录屏幕。问题就在这里。我举一个例子:

在您的手机中(例如iPhone X),您从App Store下载并安装了Facebook。然后,您登录了您的帐户。这意味着您手机中的Facebook应用现在已配置为使用您的帐户。现在,如果您要发布照片,那么如果您下载并安装另一个Facebook应用并尝试从那里发布,则将无法执行。您将必须使用配置为使用您的帐户的旧应用程序。 (实际上,您一次不能下载两个文件:P)

以相同的方式,您应该告诉堆栈导航器导航到堆栈导航器的Login屏幕,而不是渲染另一个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 } } } 中,将onPress道具从Login.js更改为this.props.navigation.navigate('Signup')

您现在将不需要堆栈导航器。(现在您拥有自己的导航器)因此,不用使用该堆栈导航器,您现在可以直接使用this.props.onSignUpPress()屏幕。现在,您只需删除stacknavigator.js文件即可。

我想这应该可以解决。

提示:看到文件中有许多未使用的样式和导入。如果您真的不打算使用它们,则只需删除这些行即可。这取决于你。

编辑:

要将功能传递到导航器中,可以使用screenProps属性。

编辑您的Welcome

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。 这应该起作用。