【问题标题】:How to jump another page after login/sign up登录/注册后如何跳转另一个页面
【发布时间】:2024-04-28 23:10:03
【问题描述】:

我使用 react-navigation v3 构建导航并使用 firebase 进行身份验证。没问题。导航流程有效,我可以注册。我面临的问题是,当我按下注册按钮时,它不会跳转到注册屏幕。

所以 Build: in App.js 的结构我正在做导航部分。首先发送包含登录的欢迎屏幕。

这是欢迎屏幕:

import React, { Component } from 'react'
import {StyleSheet, View } from "react-native";
import {Container, Text, Form, Content, Header, Button, Input, Label, Item} from 'native-base';
import SignUp from '../screens/register/SignUp'
import * as firebase from 'firebase';

const firebaseConfig = {
    apiKey: "example example",
    authDomain: "example example",
    databaseURL: "example example",
    projectId: "example example",
    storageBucket: "example example",
};
firebase.initializeApp(firebaseConfig);


export default class WelcomeScreen extends Component {
    constructor(props){
        super(props)

        this.state = ({
            email: '',
            password: ''
        })
    }

    loginUser = (email, password, navigate) => {
        try {
            firebase.auth().signInWithEmailAndPassword(email,password).then(function(user){
                console.log(user);
                navigate('Learn')
            })
        }
        catch (error) {
            console.log(error.toString())
        }
    };

    render() {
        return (
            <Container style={styles.container}>
                <Form>
                    <Item floatingLabel>
                        <Label>E-mail</Label>
                        <Input
                            autocorrect={false}
                            autoCapitalize={'none'}
                            onChangeText={(email) => this.setState({email})}
                        />
                    </Item>
                    <Item floatingLabel>
                        <Label>Password</Label>
                        <Input
                            secureTextEntry={true}
                            autocorrect={false}
                            autoCapitalize={'none'}
                            onChangeText={(password)=>this.setState({password})}
                        />
                    </Item>
                </Form>
                <Button style={{backgroundColor:'#6c5ce7', marginTop: 10}}
                    onPress={()=>this.loginUser(this.state.email,this.state.password)}
                    rounded
                    success
                >
                    <Text>Kelimeda'ya Uç</Text>
                </Button>
                <Button style={{backgroundColor:'#6c5ce7', marginTop: 10}}
                    onPress={()=>this.props.navigation.navigate('SignUp')}
                    rounded
                    primary
                >
                    <Text>Beni Kaydet!</Text>
                </Button>
            </Container>
        );
    }
}

注册屏幕:

import React, { Component } from 'react'
import {StyleSheet, View } from "react-native";
import {Container, Text, Form, Content, Header, Button, Input, Label, Item} from 'native-base';
import * as firebase from 'firebase';



export default class WelcomeScreen extends Component {
    constructor(props){
        super(props)

        this.state = ({
            email: '',
            password: ''
        })
    }

    signUpUser = (email, password) => {
        try {
            if(this.state.password.length < 6){
                alert('Lutfen 6 dan daha uzun bir karakter giriniz.')
                return
            }
            firebase.auth().createUserWithEmailAndPassword(email,password)
        }
        catch (error) {
            console.log(error.toString())
        }
    };

    render() {
        return (
            <Container style={styles.container}>
                <Form>
                    <Item floatingLabel>
                        <Label>E-mail</Label>
                        <Input
                            autocorrect={false}
                            autoCapitalize={'none'}
                            onChangeText={(email) => this.setState({email})}
                        />
                    </Item>
                    <Item floatingLabel>
                        <Label>Password</Label>
                        <Input
                            secureTextEntry={true}
                            autocorrect={false}
                            autoCapitalize={'none'}
                            onChangeText={(password)=>this.setState({password})}
                        />
                    </Item>
                </Form>
                <Button style={{backgroundColor:'#6c5ce7', marginTop: 10}}
                        onPress={()=>this.signUpUser(this.state.email,this.state.password)}
                        rounded
                        primary
                >
                    <Text>Beni Kaydet!</Text>
                </Button>
            </Container>
        );
    }
}


const styles = StyleSheet.create({
    container: {
        flex: 1,
        padding: 5,
        justifyContent: 'center',
        backgroundColor: '#fff',
    },
}); 

这是应用程序屏幕。我是否需要在此处检查用户是否已登录?还是欢迎屏幕?

//imports...

import React, { Component } from 'react';
import {View, StatusBar} from 'react-native';
import {
  createSwitchNavigator,
  createAppContainer,
  createDrawerNavigator,
  createBottomTabNavigator,
  createStackNavigator,} from 'react-navigation';
import Icon from 'react-native-vector-icons/Ionicons';
import WelcomeScreen from './src/screens/Welcome';
import Learn from './src/screens/Tab/Learn';
import Settings from './src/screens/Tab/Settings';
import Play from './src/screens/Tab/Play';


//content: const & functions and styles...

const DashboardTabNavigator = createBottomTabNavigator({
  Play,
  Learn,
  Settings
},
{
  navigationOptions: ({navigation}) => {
    const {routeName} = navigation.state.routes
        [navigation.state.index];
    return {
      headerTitle: routeName,
      headerTintColor:'#fff',
      headerStyle:{
        backgroundColor: '#2c3e50',
      }
    };
  }
});

const DashStack = createStackNavigator({
  DashboardTabNavigator: DashboardTabNavigator
}, {
  defaultNavigationOptions:({navigation}) =>{
    return {
      headerLeft: <Icon
          style={{paddingLeft: 15, color:'#fff'}}
          onPress={()=>navigation.openDrawer()}
          name={'md-menu'}
          size={30}
          />
    }
  },
});

const appDrawNavigator = createDrawerNavigator({
  Dashboard:{ screen: DashStack }
});

const appSwitchNavigation = createSwitchNavigator({
  Welcome:{ screen: WelcomeScreen },
  Dashboard:{ screen: appDrawNavigator }
});

const AppContainer = createAppContainer(appSwitchNavigation);


class App extends Component {
  render() {
    return(
        <View style={{flex: 1}}>
          <StatusBar
            backgroundColor="blue"
            barStyle="light-content"
         />
          <AppContainer/>
          </View>

    ) ;
  }
}
export default App;

【问题讨论】:

    标签: react-native firebase-authentication react-navigation react-navigation-stack


    【解决方案1】:

    问题 1 的解决方案:您还没有通过导航到您的 loginUser 函数,所以它不起作用。请像这样将导航参数发送到loginUser

    <Button
       style={{backgroundColor:'#6c5ce7', marginTop: 10}}
       onPress={()=>this.loginUser(this.state.email,this.state.password, this.props.navigation.navigate)}
       rounded
       success>
    

    问题 2 的解决方案: 对于 firebase 重复问题,这是因为您在应用程序中两次初始化 firebase 实例。相反,您应该做的是,只需在应用程序根组件(如 App.js 或启动画面)初始化 firebase,这样它就可以在整个应用程序生命周期中可用,并且只要您需要使用它,只需将其导入并使用。

    问题 3 的解决方案:这是一个常见的用例,即预先了解用户的登录状态,以便将用户适当地导航到应用程序中。 为此,您可以做的是,只需在AsyncStorage 中保存一个标志,例如。成功登录后isLoggedInYES 一样,并发布此信息,每当打开应用程序时,只需分析标志的存在/值是否用户已登录。执行此操作的好地方是应用的 Splashscreen 组件或应用的根组件。

    已编辑答案(附加):(针对问题 1)

    您的导航路线嵌套错误,无法直接跳转到 Learn from 欢迎屏幕,要从一个屏幕导航到另一个屏幕,这两个屏幕应该在相同的导航范围内(如果导航器在另一个导航器中作为路线给出,则路线导航器被视为一个屏幕,用户将被导航到其初始路线当导航到它时)

    您的代码应该定位到导航到Dashboard 路由,这将在内部呈现嵌套的导航器,即第一个/初始路由,但是在当前嵌套的情况下,这将使您到达Play,所以可以做的是,使Learn as first/initial route您的标签导航器。

    loginUser 中的代码应为navigate('Dashboard'),并且您的标签导航器应将Learn 作为其初始路径。

    【讨论】:

      【解决方案2】:

      您的登录功能如下所示:

       loginUser = (email, password, navigate) => {
              try {
                      firebase.auth().signInWithEmailAndPassword(email,password).then(function(user){
                      console.log(user);
                      navigate('Learn')
                  })
              }
              catch (error) {
                  console.log(error.toString())
              }
          };
      

      这个函数需要三个参数。您应该将this.props.navigation.navigate 传递给登录函数以使用navigation('Learn')

      <Button 
        style={{backgroundColor:'#6c5ce7', marginTop: 10}}
        onPress={()=>this.loginUser(this.state.email,this.state.password,this.props.navigation.navigate)}
        rounded
        success
       >
      

      【讨论】: