美文网首页
React-Navigation实现身份认证导航

React-Navigation实现身份认证导航

作者: xsic | 来源:发表于2018-12-12 15:36 被阅读24次

    一、前言

    现在大多数的App都具备用户功能,就拿微信来说,当第一次登录时输入账号密码登录成功之后进入app主页面,此时再按返回键,原本属于前一个页面的账号输入页已经没有了,这是如何实现的?

    二、安装

    1、安装react-navigation

    在命令行中敲入(yarn默认--save,因此不用加上)
    yarn add react-navigation

    npm i react-navigation --save

    2、安装react-native-gesture-handler

    yarn add react-native-gesture-handler

    npm install --save react-native-gesture-handler

    3、安装react-native-storage(可选,用于自动登录)

    yarn add react-native-storage

    npm install --save react-native-storage

    4、链接依赖

    react-native link

    三、使用

    总体思路是这样的,创建两个StackNavigation,一个包含登录前所展示的页面(登录、注册等),另一个包含登录后所展示的页面(程序主页面),然后通过react-navigation中的createSwitchNavigator(官网链接https://reactnavigation.org/docs/zh-Hans/auth-flow.html)将两个StackNavigation连起来。

    完整代码:

    import React, { Component } from 'react';
    import {
        Text,
        StyleSheet,
        View,
        Button
    } from 'react-native';
    import { 
        createAppContainer,
        createStackNavigator,
        createSwitchNavigator,
        createBottomTabNavigator
     } from 'react-navigation';
    
    class FirstPage extends React.Component{
        constructor(props){  
            super(props)
            this.state = {};
        }
        _toLogin=()=>{
            this.props.navigation.navigate('Login')
        }
        _toRegister=()=>{
          this.props.navigation.navigate('Register')
        }
        render(){
            return(
                <View style={{flex:1,justifyContent:'center',alignItems:'center'}}>
                    <Text>First Page!</Text>
                    <Button 
                      title="toLogin"
                      onPress={this._toLogin}
                    />
                    <Button 
                      title="toRegister"
                      onPress={this._toRegister}
                    />
                </View>
            )
        }
    }
    class Login extends React.Component{
        constructor(props){
            super(props)
            this.state = {};
        }
        _press=()=>{
            this.props.navigation.navigate('TabNav')
        }
        render(){
            return(
                <View style={{flex:1,justifyContent:'center',alignItems:'center'}}>
                    <Text>Login!</Text>
                    <Button 
                      title="模拟登录"
                      onPress={this._press}
                    />
                </View>
            )
        }
    }
    class Register extends React.Component{
        constructor(props){
            super(props)
            this.state={}
        }
        _press=()=>{
            this.props.navigation.navigate('Third')
        }
        render(){
            return(
                <View style={{flex:1,justifyContent:'center',alignItems:'center'}}>
                    <Text>Register!</Text>
                </View>
            )
        }
    }
    class HomeScreen extends React.Component{
        constructor(props){
            super(props)
            this.state={}
        }
        _press=()=>{
            this.props.navigation.navigate('Detail')
        }
        render(){
            return(
                <View style={{flex:1,justifyContent:'center',alignItems:'center'}}>
                    <Text>这是Home页面!</Text>
                    <Button 
                      title="toDetail"
                      onPress={this._press}
                    />
                </View>
            )
        }
    }
    class MeScreen extends React.Component{
      constructor(props){
          super(props)
          this.state={}
      }
      render(){
          return(
              <View style={{flex:1,justifyContent:'center',alignItems:'center'}}>
                  <Text>这是Me页面!</Text>
              </View>
          )
      }
    }
    class Detail extends React.Component{
      constructor(props){
          super(props)
          this.state={}
      }
      render(){
          return(
              <View style={{flex:1,justifyContent:'center',alignItems:'center'}}>
                  <Text>这是Home页面中的Detail页面!</Text>
              </View>
          )
      }
    }
    
    const TabNav = createBottomTabNavigator({
        //这是TabNavigation,也就是屏幕底部的两个标签
        Home : HomeScreen,
        Me : MeScreen
    })
    const AuthNav = createStackNavigator({
        //这是模拟验证的页面,当验证成功后在app主页面再按返回键就不会回到这些页面了,而是直接
        //跳出程序
        FirstPage : FirstPage,
        Login : Login,
        Register : Register
    })
    const AppNav = createStackNavigator({
        //app主页面,包含一个TabNavigation和一个子页面
        TabNav : TabNav,
        Detail : Detail
    
    })
    export default createAppContainer(createSwitchNavigator(
        {
            Auth : AuthNav,
            App : AppNav
        },
        
    ))
    

    四、注意项

    1、

    从react-navigation 2.x迁移至3.x,3.x版本对比2.x版本有了一些比较大的变化
    例如说:
    2.x版本不需要显式指定AppContainer,因为AppContainer在你使用createXXXNavigator(createStackNavigator、createTabNavigator....)的时候已经提供了;
    3.x版本需要你显式指定AppContainer,也就是当你准备将写好的导航export出去的时候,记得在外面加一个api :createAppContainer ,如下:

    export default createAppContainer(createSwitchNavigator(
        {
            Auth : AuthNav,
            App : AppNav
        }, 
    ))
    

    还有更多变化详见(https://reactnavigation.org/blog/#breaking-changes

    2、

    如果你想做自动登录,只需要在该demo上做一点小小的改变,

    安装react-native-storage,这是一个在官方API AsyncStorage 上进行封装的第三方库(https://github.com/sunnylqm/react-native-storage#readme),当然你也可以选择其他你喜欢的持久化方案

    yarn add react-native-storage
    

    创建storage.js

    import Storage from 'react-native-storage';
    import { AsyncStorage } from 'react-native'
    let storage = new Storage({
        size: 1000,
        storageBackend: AsyncStorage,
        defaultExpires: 1000 * 3600 * 24,
        enableCache: true,
    });
    module.exports = storage;
    

    新增一个组件AuthLoading,作用是检查本地是否有token,有的话用这个token进行登录,然后直接跳转至主页面;没有的话显示登录注册页面

    class AuthLoading extends React.Component{
      constructor(props){
        super(props)
        this.state={}
        this.loadWhichScreen()//立即执行
      }
      loadWhichScreen(){
        storage.load({
          key : 'autoLogin'
        }).then((ret)=>{
          //代表从本地获取token成功,接着进行自动登录
          //   ...此处应该是自动登录的操作,本例省略...
          this.props.navigation.navigate('TabNav')
        }).catch(()=>{
          //表示本地没有token,显示登录注册页面
          this.props.navigation.navigate('FirstPage')
        })
      }
      render(){
        return(
          //这里最好有一个modal,显示操作正在进行,本例省略
          null
        )
      }
    }
    

    修改AuthNav:

    const AuthNav = createStackNavigator({
       
          AuthLoading : AuthLoading,
          FirstPage : FirstPage,
          Login : Login,
          Register : Register
    })
    

    修改Login中的_press方法:

    _press=()=>{
          storage.save({
            key : 'autoLogin',
            data : {
              id : '123',
              password : '123'
            }
          }).then(()=>{
            this.props.navigation.navigate('TabNav')
          }).catch((err)=>{
            //处理错误
            console.log(err)
          })  
        }
    

    完整代码

    App.js

    import React, { Component } from 'react';
    import {
        Text,
        StyleSheet,
        View,
        Button
    } from 'react-native';
    import { 
        createAppContainer,
        createStackNavigator,
        createSwitchNavigator,
        createBottomTabNavigator
     } from 'react-navigation';
    import storage from './storage'
    
    class FirstPage extends React.Component{
        constructor(props){  
            super(props)
            this.state = {};
        }
        _toLogin=()=>{
            this.props.navigation.navigate('Login')
        }
        _toRegister=()=>{
          this.props.navigation.navigate('Register')
        }
        render(){
            return(
                <View style={{flex:1,justifyContent:'center',alignItems:'center'}}>
                    <Text>First Page!</Text>
                    <Button 
                      title="toLogin"
                      onPress={this._toLogin}
                    />
                    <Button 
                      title="toRegister"
                      onPress={this._toRegister}
                    />
                </View>
            )
        }
    }
    class Login extends React.Component{
        constructor(props){
            super(props)
            this.state = {};
        }
        _press=()=>{
          storage.save({
            key : 'autoLogin',
            data : {
              id : '123',
              password : '123'
            }
          }).then(()=>{
            this.props.navigation.navigate('TabNav')
          }).catch((err)=>{
            //处理错误
            console.log(err)
          })  
        }
        render(){
            return(
                <View style={{flex:1,justifyContent:'center',alignItems:'center'}}>
                    <Text>Login!</Text>
                    <Button 
                      title="模拟登录"
                      onPress={this._press}
                    />
                    
                </View>
            )
        }
    }
    class Register extends React.Component{
        constructor(props){
            super(props)
            this.state={}
        }
        _press=()=>{
            this.props.navigation.navigate('Third')
        }
        render(){
            return(
                <View style={{flex:1,justifyContent:'center',alignItems:'center'}}>
                    <Text>Register!</Text>
                </View>
            )
        }
    }
    class HomeScreen extends React.Component{
        constructor(props){
            super(props)
            this.state={}
        }
        _press=()=>{
            this.props.navigation.navigate('Detail')
        }
        render(){
            return(
                <View style={{flex:1,justifyContent:'center',alignItems:'center'}}>
                    <Text>这是Home页面!</Text>
                    <Button 
                      title="toDetail"
                      onPress={this._press}
                    />
                </View>
            )
        }
    }
    class MeScreen extends React.Component{
      constructor(props){
          super(props)
          this.state={}
      }
      render(){
          return(
              <View style={{flex:1,justifyContent:'center',alignItems:'center'}}>
                  <Text>这是Me页面!</Text>
              </View>
          )
      }
    }
    class Detail extends React.Component{
      constructor(props){
          super(props)
          this.state={}
      }
      render(){
          return(
              <View style={{flex:1,justifyContent:'center',alignItems:'center'}}>
                  <Text>这是Home页面中的Detail页面!</Text>
              </View>
          )
      }
    }
    
    class AuthLoading extends React.Component{
      constructor(props){
        super(props)
        this.state={}
        this.loadWhichScreen()//立即执行
      }
      loadWhichScreen(){
        storage.load({
          key : 'autoLogin'
        }).then((ret)=>{
          //代表从本地获取token成功,接着进行自动登录
          //   ...此处应该是自动登录的操作,本例省略...
          this.props.navigation.navigate('TabNav')
        }).catch(()=>{
          //表示本地没有token,显示登录注册页面
          this.props.navigation.navigate('FirstPage')
        })
      }
      render(){
        return(
          //这里最好有一个modal,显示操作正在进行
          null
        )
      }
    }
    
    const TabNav = createBottomTabNavigator({
        //这是TabNavigation,也就是屏幕底部的两个标签
        Home : HomeScreen,
        Me : MeScreen
    })
    const AuthNav = createStackNavigator({
        //这是模拟验证的页面,当验证成功后在app主页面再按返回键就不会回到这些页面了,而是直接
        //跳出程序
        AuthLoading : AuthLoading,
        FirstPage : FirstPage,
        Login : Login,
        Register : Register
    })
    const AppNav = createStackNavigator({
        //app主页面,包含一个TabNavigation和一个子页面
        TabNav : TabNav,
        Detail : Detail
    
    })
    export default createAppContainer(createSwitchNavigator(
        {
            Auth : AuthNav,
            App : AppNav
        },
        
    ))
    

    创建storage.js

    import Storage from 'react-native-storage';
    import { AsyncStorage } from 'react-native'
    let storage = new Storage({
        size: 1000,
        storageBackend: AsyncStorage,
        defaultExpires: 1000 * 3600 * 24,
        enableCache: true,
    });
    module.exports = storage;
    

    五、结语

    本文较为详细地展示了如何使用react-navigation实现身份认证,希望能够帮助到有需要的人。

    相关文章

      网友评论

          本文标题:React-Navigation实现身份认证导航

          本文链接:https://www.haomeiwen.com/subject/tdkehqtx.html