1

a) User navigates to some screen B in app. Backgrounds the app.

b) User opens app --> app always opens to initialRouteName (Loading --> first screen in Tab Navigator "Screen A"). This is unexpected since was previously using on Screen B.

Similarly, when opening the app from a notification, the Loading route is called, which then directs to TabNavigator first screen. I think I could store navigation history, then check for prior screen state if opening from foreground in the "Loading" screen. For the notification case, I could store notification params on tap, then pull notification parameters from storage to direct user to that specific page. This seems super cumbersome, and I wonder if there is a better way.

//Navigator
const SwitchNavigator = createSwitchNavigator(
  {
    TabNavigator,
    Auth,
    Loading
  },
  {
    initialRouteName: "Loading"
  }
);

//Loading.js
componentDidMount() {
   signedIn ? this.props.navigation.navigate(TabNavigator)
       : this.props.navigation.navigate(Auth)
  }

1 Answer 1

1

I've solved this issue using React Context. I store the current screen in a context object's property and when app returns to foreground, in the initial route, I get the value of the current screen from context and navigate to it.

Something like that:

// context.js
import { createContext } from 'react';
export const AppContext = createContext({
    currentScreen: null,
});


// rootManager.js
import React, { useContext, useState } from 'react';
import { NavigationContainer } from '@react-navigation/native';
import { createStackNavigator } from '@react-navigation/stack';
import Loading from 'loading';
import ScreenA from 'screenA';
import ScreenB from 'screenB';
import ScreenC from 'screenC';
import { AppContext } from 'context';
const Stack = createStackNavigator();
function RootManager() {
    const appContext = useContext(AppContext);
    const [initialRoute, setInitialRoute] = useState('Loading');
    // Initializing code ...  
    return (
        <AppContext.Provider value={appContext}>
            <NavigationContainer>
                <Stack.Navigator initialRouteName={initialRoute} headerMode='none'>
                    <Stack.Screen name='Loading' component={Loading} />
                    <Stack.Screen name='ScreenA' component={ScreenA} />
                    <Stack.Screen name='ScreenB' component={ScreenB} />
                    <Stack.Screen name='ScreenC' component={ScreenC} />
                </Stack.Navigator>
            </NavigationContainer>
        </AppContext.Provider>
    );
}
export default RootManager;

// loading.js
import React, { useContext } from 'react';
import { AppContext } from 'context';
function Loading({ navigation }) {
    const appContext = useContext(AppContext);
    // Control code ... 
    const cacheResourcesAsync = async () => {
        // Loading code ...    
        navigation.navigate(appContext.currentScreen || 'ScreenA');
    };
    return (
        // Rendering code ...
      );
}
export default Loading;

// screenA.js
import React, { useContext } from 'react';
import { AppContext } from 'context';
function ScreenA({ navigation }) {
    const appContext = useContext(AppContext);
    appContext.currentScreen = 'ScreenA';
    // Control code ...  
    return (
        // Rendering code ...
      );
}
export default ScreenA;

// screenB.js
import React, { useContext } from 'react';
import { AppContext } from 'context';
function ScreenB({ navigation }) {
    const appContext = useContext(AppContext);
    appContext.currentScreen = 'ScreenB';
    // Control code ...  
    return (
        // Rendering code ...
      );
}
export default ScreenB;

// screenC.js
import React, { useContext } from 'react';
import { AppContext } from 'context';
function ScreenC({ navigation }) {
    const appContext = useContext(AppContext);
    appContext.currentScreen = 'ScreenC';
    // Control code ...  
    return (
        // Rendering code ...
      );
}
export default ScreenC;
Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.