javascript - 根据登录 token react 屏幕之间的 native 切换

标签 javascript android reactjs react-native

我正在构建一个 React native 应用程序,我是新手。我目前有 3 个文件 -

1) 应用.js

2) 登录.js

3) 飞行列表.js

当我没有登录时,我需要显示登录屏幕。当我登录时,我需要存储 token 并显示航类列表屏幕。

这是我的代码 -

App.js

import React, { Component } from 'react';
import {
  Platform,
  StyleSheet,
  Text,
  View
} from 'react-native';
import { StackNavigator } from 'react-navigation';
import Login from './Login';

export default class App extends React.Component {
  render() {
    return (
      <View style={styles.container}>
        //Check if token is there and if there show flight list screen else login screen
      </View>
    );
  }
}

登录.js

'use strict';
import React, { Component } from 'react';
import {
  StyleSheet,
  TextInput,
  TouchableHighlight,
  AsyncStorage,
  Text,
  View
} from 'react-native';
import {
    StackNavigator,
  } from 'react-navigation';
  import FlightList from './FlightList';


  const FlightListScreen = StackNavigator({
    FlightList: { screen: FlightList }
  });

const ACCESS_TOKEN = 'access_token';

export default class Login extends Component {
  constructor(props){
    super(props);

    this.state = {
      email: "",
      password: "",
      error: ""
    }
  }


async storeToken(accessToken){
      try {
          await AsyncStorage.setItem(ACCESS_TOKEN, accessToken);
      } catch (error) {
          console.log("something went wrong");
      }
    }

  async onLoginPressed() {
    try {
      const reqOptions = {
        method: 'POST',
        headers: {
          'Accept': 'application/json',
          'Content-Type': 'application/json',
        },
        body: JSON.stringify({

            email: this.state.email,
            password: this.state.password,

        })
      };

      console.log("error of json is " + JSON.stringify(reqOptions))
      let response = await fetch('https://...login', reqOptions);

      if (response.status >= 200 && response.status < 300) {
        const body = await response.json();
          this.storeToken(body.token);
          this.props.navigation.navigate('FlightListScreen');
      } else {
          //Handle error
          let error = res;
          throw error;
      }
    } catch(error) {
        this.setState({error: error});
        console.log("error " + error);
    }
  }
  render() {

    return (
      <View style={styles.container}>
      //view here
      </View>
    );
  }
}

航类列表.js

'use strict';
import React, { Component } from 'react';
import {
  StyleSheet,
  TextInput,
  TouchableHighlight,
  AsyncStorage,
  Text,
  View
} from 'react-native';
import {
    StackNavigator,
  } from 'react-navigation';

const ACCESS_TOKEN = 'access_token';

export default class FlightList extends Component {
  constructor(props){
    super(props);
  }


async getToken() {
    try {
        let token = await AsyncStorage.getItem(ACCESS_TOKEN);
        console.log("token is" + token);
    } catch (error) {
        console.log("error while getting token");
    }
 }

 async getFlights() {
    try {
        const reqOptions = {
          method: 'GET',
          headers: {
            Authorization: `Bearer ${getToken()}`
          },
          body: JSON.stringify({
            // no body since it is GET call

          })
        };

        let response = await fetch('https://.../flights', reqOptions);

        if (response.status >= 200 && response.status < 300) {
          const body = await response.json();
          //update the view
        } else {
            //Handle error
            let error = res;
            throw error;
        }
      } catch(error) {
          this.setState({error: error});
          console.log("error " + error);
      }
 }



 componentDidMount(){
    getFlights();
  }
}

我的问题是-

1) 在 App.js 中,我如何检查 token 是否存在以及是否显示航类列表屏幕或登录屏幕

2) 还有 getToken() 方法,我如何在全局范围内使用它,因为我需要它作为所有 API 调用的 header

最佳答案

您可以创建另外两个文件,第一个是实用程序文件,包含定义全局所需的所有必要函数。例如,您的 getToken 将是这样的:

export default class Utility {

    static async getToken() {
        try {
            let token = await AsyncStorage.getItem(ACCESS_TOKEN);
            return token
        } catch (error) {
            console.log("error while getting token");
            return 'error
        }
    }
}

如果您在函数之前使用 static,则可以在导入 Utility 文件的每个地方使用该函数。

对于您的第一个问题...您可以制作启动画面并检查 token 并决定导航到哪个页面。我建议您为 api 请求创建一个文件,为路由器创建另一个文件。您可以在 router.js 中定义所有路由定义并使用它启动应用程序:

import React, { Component } from 'react';
import { View } from 'react-native';
import { StackNavigator, TabRouter, DrawerNavigator } from 'react-navigation';
import Splash from './../views/SplashScreen'
import Login from './../views/Login'
import Verification from './../views/Verification'
import Home from './../views/Home'
import Contents from './../views/Contents'
import ContentList from './../views/ContentList'
import MessageInbox from './../views/MessageInbox'

export default class AppRouter extends Component {

    public static Routes = StackNavigator({
    SplashScreen: { screen: Splash },
    Login: { screen: Login },
    Verification: { screen: Verification },
    Private: {
        screen: DrawerNavigator({
            Main: {
                screen: StackNavigator({
                    Home: { screen: Home },
                    Contents: { screen: Contents },
                    ContentList: { screen: ContentList },
                }, { initialRouteName: 'Home' })
            },
            MessageInbox: { screen: MessageInbox },
        }, { initialRouteName: 'Main' })
    }
}, { initialRouteName: 'SplashScreen' })

render() {
    return (
        <View></View>
    )
}

}

index.js 将是:

import React, { Component } from 'react';
import AppRouter from './../router/routes';
export default class App extends Component {
    render() {
        return (
            <AppRouter.Routes />
        )
    }
}

希望能帮到你

编辑:

如果您使用 AppRouter,它将成为您应用程序的启动器和它调用的第一个页面,因此它有一个 navigation prop。如果你想导航到每个页面,你可以只使用 this.props.navigation.navigate('FlightList') 。请记住,如果您在页面中使用一个组件并且您想要从该组件导航,您需要将 this.props.navigation 作为 prop 传递给该组件,并且然后,它可以更改堆栈导航。 在你的情况下,你的页面将是这样的......:

路由器.js

export default class AppRouter extends Component {

public static Routes = StackNavigator({
    SplashScreen: { screen: Splash },
    Login: { screen: Login },
    FlightList: { screen: FlightList},
}, { initialRouteName: 'SplashScreen' })

render() {
    return (
        <View></View>
    )
}
}

SplashScreen.js:

export default class SplashScreen extends Component {
constructor(props) {
    super(props);
    let token = Check token...
    if (token) {
        this.props.navigation.navigate('FlightList')
    } else {
        this.props.navigation.navigate('Login')
    }
}
render() {
    return (
        <View style={{ flex: 1 }}>
            <Text>Loading...</Text>
        </View>
    )
}
}

关于javascript - 根据登录 token react 屏幕之间的 native 切换,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/50684751/

相关文章:

javascript - 在 css 仍然适用的情况下使用 javascript 添加和删除 div 样式

javascript - querySelectorAll 在使用 this.element 时仅选择第二个元素

android - 我可以直接在ios/android原生项目中使用/导入kotlin多平台库吗?

java - 如何在 ARCore 中叠加二维图像?

android - 向通知图标添加文本

reactjs - Azure 身份验证 - 访问 token 返回错误 AUD(00000003-0000-0000-c000-000000000000)

javascript - React - 用逗号解析用户输入的值并删除 CR/LF 和空格

将 unicode 符号代码转换为 HTML 中的 utf-8 的 Javascript 函数

javascript - 仅当页面未加载时才加载 requirejs 库

javascript - HOC Redux Dispatch 在子组件调用 React componentDidMount 后被调用