Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

React native switch between screens based on login token

I am building a react native app and I am new to it. I have 3 files currently -

1) App.js

2) Login.js

3) FlightList.js

When I have not logged in, I need to show login screen. When I log in, I need to store the token and display Flights list screen.

This is my code -

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>
    );
  }
}

Login.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>
    );
  }
}

FlightList.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();
  }
}

My questions is-

1) In App.js how can I check if token is there and if there show flight list screen else login screen

2) Also the getToken() method how can I use it globally since I need it as header for all the API calls


1 Answers

You can create two other files, the first one is a utility file contains all your necessary functions you need to define global. For example your getToken will be like this:

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
        }
    }
}

If you use static before your function, you can use that function every where you import Utility file.

and for your first question... you can make an splash screen and check the token and decide to navigate to which page. I advise you to create a file for your api requests and another file for router. you can define all routing definition in router.js and start app with it:

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>
    )
}

}

and index.js will be:

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

I hope i can help you

EDIT:

If you use AppRouter, it will be the starter of your app and the first page called by it so it has a navigation prop. If you want to navigate to each page, you can just use this.props.navigation.navigate('FlightList') . remember that if you are using a component in a page and you want to navigate from this component, you need to pass this.props.navigation as a prop to that component and then, it can change the stack navigation. in your case, your pages will be something like this...:

Router.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>
    )
}
}
like image 143
Ali SabziNezhad Avatar answered Mar 25 '26 16:03

Ali SabziNezhad



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!