React Native Navigation on Restart

2019-07-29 05:55发布

问题:

I am using the react-native-restart library for restarting the app so I can change the app language in the runtime. After I restart the app I want to change the first StackNavigator screen in the react-navigation library after restarting the app.

Navigator class is like this

import Screen1 from './Screen1'
import Screen2 from './Screen2'
import Screen3 from './Screen3'
import {StackNavigator} from 'react-navigation';

const Navigator = StackNavigator({
    Screen1: {
        screen: Screen1
    },
    Screen2: {
        screen: Screen2
    },
    Screen3: {
        screen: Screen3
    }
});

export default Navigator;

in screen 2 I change the language and restart the app by the following function:

_onDirectionChange = () => {
      I18nManager.forceRTL(true);
      // Immediately reload the React Native Bundle
      RNRestart.Restart();  }

回答1:

Maybe you can save a paramater in the mobile settings and make a condition based on it to load the correct Navigator on load :

The code will be something like :

const Navigator = IsRestarting() ? MyNewNavigator({}) : StackNavigator({});

Where IsRestarting() can be a function that check a value store in the mobile after you ask the application to restart. For example if the value is tru you return a custom navigator, if not you return the default.

Hope it helps.



回答2:

However, fandro's answer is a good answer but there is a more straightforward answer in the following link:Change StackNavigator order #2683

There is an Option for the router called initialRouteName :

const Navigator = StackNavigator({
    Screen1: {
        screen: Screen1
    },
    Screen2: {
        screen: Screen2
    },
    Screen3: {
        screen: Screen3
    }
},{
  initialRouteName: RTL ? 'Screen2' : 'Screen1',
});

Update: Full Solution:

const Navigator = StackNavigator({
    InitialScreen: {
        screen: InitialScreen
    },
    Splash: {
        screen: Splash
    },
    LanguageStartup: {
        screen: LanguageStartup
    },
    Login: {
        screen: Login
    },
    Register: {
        screen: Register
    }
}, {initialRouteName: 'InitialScreen'});

export default Navigator;

My Initial Screen

import React, {Component} from 'react';
import {connect} from 'react-redux';
import * as GeneralPref from './../preferences/GeneralPref'
import Log from './../utils/Log'
import {AsyncStorage, View} from 'react-native';
import * as Pref from './../preferences/Preferences';
import {NavigationActions} from 'react-navigation'

const TAG = 'InitialScreen'

class InitialScreen extends Component {
    static navigationOptions = {
        header: false
      };
    componentWillMount() {
        Log(TAG+' Mount')
        const {navigate} = this.props.navigation;
        GeneralPref
            .getInitialScreen()
            .then(value => {
                Log(TAG+' Initial',value)                
                if (value != null) {
                    Log(TAG+' Initial',value)                                    
                    return value
                } else {
                    Log(TAG+' No Initial','Splash')                                    
                    return 'Splash'
                }
            })
            .then(screenName => this.props.navigation.dispatch(NavigationActions.reset({
                index: 0,
                actions: [NavigationActions.navigate({routeName: screenName})]
            })))
            .catch(err => {
                Log(TAG+' Initial Error',value)                                
                this.props.navigation.dispatch(NavigationActions.reset({
                    index: 0,
                    actions: [NavigationActions.navigate({routeName: 'Splash'})]
                }))
            });
    }
    render() {
        return null;
    }
}

export default InitialScreen;

then in Language Screen

changeLanguageTo(language) {
    Log(TAG+'Change Language', "Change Language To: " + language.code);
    // Log(TAG, 'Current State');
    Log(TAG+' Language State', language);
    GeneralPref.setInitialScreen('Login');

    this
      .props
      .actions
      .changeLanguage(language);
      I18nManager.forceRTL(true);      
    // Immediately reload the React Native Bundle
    RNRestart.Restart();
  };