0

I am using wix/react-native-navigation - v1 in my react native project and I want to launch my App based on a condition as follows:

  • Launch App
  • Read credentials from storage (AsyncStorage)
  • If credentials found, then
    • Start App with Home screen
  • Else
    • Start App with Login Screen

How can I achieve this?

I have index.js

import App from './App';

App.js

...
Navigation.registerComponent("myApp.AuthScreen", () => AuthScreen);
Navigation.registerComponent("myApp.HomeScreen", () => HomeScreen);
...

// Start a App
Navigation.startSingleScreenApp({
    screen: {
        screen: "myApp.AuthScreen",
        title: "Login"
    }
});
Gagandeep Singh
  • 827
  • 1
  • 7
  • 11

3 Answers3

1

You can have two functions that initialize single-screen apps and then call the one that fulfills the requirements.

...
Navigation.registerComponent("myApp.AuthScreen", () => AuthScreen);
Navigation.registerComponent("myApp.HomeScreen", () => HomeScreen);
...

function startHomeScreen() {
Navigation.startSingleScreenApp({
    screen: {
        screen: "myApp.HomeScreen",
        title: "Login"
    }
});
}

function startAuthScreen() {
Navigation.startSingleScreenApp({
    screen: {
        screen: "myApp.AuthScreen",
        title: "Home"
    }
});
}

function init() {
   if(...) {
      startAuthScreen();
   } else {
      startHomeScreen();
   }
}

Filip Ilievski
  • 317
  • 1
  • 8
  • In this case, how will we use AsyncStorage (https://github.com/react-native-community/react-native-async-storage)? When I try to do 'AsyncStorage.getItem' which is asynchronous, the app somehow remains in blank white splashscreen. – Gagandeep Singh Apr 17 '19 at 17:06
1

It worked! I am not sure why the app kept hanging on splashscreen. Following is the exact code:

const __init__ = () => {
    try {
        AsyncStorage.getItem("MY-KEY")
            .then((value) => {
                if (value) {
                    startHomeScreen();
                } else {
                    startAuthScreen();
                }
            });
    } catch (e) {
        startAuthScreen();
    }
};
__init__();

Thanks @Filip Ilievski !

Gagandeep Singh
  • 827
  • 1
  • 7
  • 11
  • And the reason why the splash screen was stuck is that JS is single threaded and the RN main (UI) thread has been blocked, or better said, the JS thread never "resolved" and sent the info for what needs to be rendered next to the main thread. How this happened - previously, you haven't resolved the getItem() promise. – Filip Ilievski Apr 18 '19 at 08:28
0
Navigation.registerComponent("RootScreen", () => RootScreen);

Navigation.startSingleScreenApp({
    screen: {
        screen: "RootScreen",
        title: "Root"
    }
});

For this scenarios you can create one additional component like below. This additional component will check your condition in async storage and decide which view to load first

import AuthScreen from './AuthScreen';
import HomeScreen from './HomeScreen';

class RootScreen {
  constructor(props) {
    super(props);
    this.state = {
      loaded: false,
      screenToLoad: ''
    };
  }

  componentDidMount() {
    this.checkRoute();
  }

  checkRoute = () => {
    AsyncStorage.getItem("MY-KEY")
      .then((value) => {
        this.setState({
          loaded: true,
          screenToLoad: value
        });
      });
  }

  renderRoute = () => {
    const { screenToLoad } = this.state;
    switch(screenToLoad) {
      case 'AuthScreen':
        return <AuthScreen />;

      case 'HomeScreen':
        return <HomeScreen />

      default:
        return null;
    }
  }

  render () {
    const { loaded } = this.state;
    if (!loaded) return null;
    return this.renderRoute();
  }
}