React-Native: условный запуск приложения в wix / react-native-navigation — v1

#react-native #wix-react-native-navigation

#реагировать-родной #wix-react-native-navigation

Вопрос:

Я использую wix / react-native-navigation — v1 в своем проекте react native, и я хочу запустить свое приложение на основе следующего условия:

  • Запустить приложение
  • Считывание учетных данных из хранилища (AsyncStorage)
  • Если учетные данные найдены, то
    • Запустите приложение с главного экрана
  • Ещё
    • Запустите приложение с экрана входа в систему

Как я могу этого добиться?

У меня есть 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"
    }
});
 

Ответ №1:

У вас может быть две функции, которые инициализируют одноэкранные приложения, а затем вызывают ту, которая соответствует требованиям.

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

 

Комментарии:

1. В этом случае, как мы будем использовать AsyncStorage ( github.com/react-native-community/react-native-async-storage )? Когда я пытаюсь выполнить ‘AsyncStorage.GetItem’, который является асинхронным, приложение каким-то образом остается на пустом белом экране.

Ответ №2:

Это сработало! Я не уверен, почему приложение продолжало зависать на заставке. Ниже приведен точный код:

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

Спасибо @Filip Ilievski!

Комментарии:

1. И причина, по которой заставка застряла, заключается в том, что JS является однопоточным, а основной поток RN (UI) заблокирован, или, лучше сказать, поток JS никогда не «разрешался» и отправлял информацию о том, что нужно отобразить рядом с основным потоком. Как это произошло — ранее вы не разрешили обещание GetItem().

Ответ №3:

 Navigation.registerComponent("RootScreen", () => RootScreen);

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

Для этих сценариев вы можете создать один дополнительный компонент, как показано ниже.
Этот дополнительный компонент проверит ваше состояние в асинхронном хранилище и решит, какое представление загружать первым

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