1

In short, I am trying to find a proper way of doing an authentication flow with multiple screens for each set. However, one feature I would want it to have is on Expo reload it returns to the current page state using the state that has been persisted in AsyncStorage using state persistence.

If you look at the tab navigator template from Expo and add the persist storage then changes to higher elements would restore to the same tab that was last visited. I want to keep that behaviour since I have an app screen structure that has stack navigators on top of a tab navigator. That is...

<NativeStackNavigator>
  <BottomTabNavigator>
    <Screen>
      <StackNavigator>
        <Screen />
         ...
      </StackNavigator>
    </Screen>
    <Screen>
      <StackNavigator>
        <Screen />
         ...
      </StackNavigator>
    </Screen>
  </BottomTabNavigator>
  <Group modals="">...</Group>
</NativeStackNavigator>

So sometimes if you're working on a nested screen if there is a reload it will bring you back to the initial screen.

(I know this only applies to development, just trying to make the DX a little bit better so they don't have to renavigate to the screen they are working on if they wanted to add additional state to a higher level context).

What I've checked so far:

Related:

I'm not doing deep linking at least not to my knowledge. So these two don't really apply

History

I'm looking at React Navigation authentication flow this was what our app used to have before we changed the navigation structure.

I'm revisiting it again because when we first had the app what we noticed was when there was a "reload" on Expo it kept on bringing us back to the "home" screen of the app rather than where we last were.

Their approach is

isAuthenticated ? <>
  <Stack.Screen name="HomeScreen" />
  <Stack.Screen name="SecureScreen" />
</> : <>
  <Stack.Screen name="SignInScreen" />
  <Stack.Screen name="SignUpScreen" />
</>

What I suspecting happens is since my isAuthenticated is a useState stored in a React.Context way above my tree and React.Context provides a default which is {isAuthenticated: false} much like the another React-Navigation Authentication Flow question. When there's a reload it starts with false and applies the render path and state accordingly.

What I've done so far

Here's conceptually what I've done. Namely just remove the isAuthenticated check and simplify the whole navigation tree. But I am not sure if this is the most ideal way of doing it because now everything is intermingled.

<NavigationContainer initialState={...} onStateChange={...}>
  <Stack.Navigator>
    <Stack.Screen name="HomeScreen" />
    <Stack.Screen name="SecureScreen" />
    <Stack.Screen name="SignInScreen" />
    <Stack.Screen name="SignUpScreen" />
  </Stack.Navigator>
</NavigationContainer>

What I haven't done but I am thinking of

  • Have two <NavigationContainer>s each storing it's own persisted state (though authentication likely won't store a state because I always want it to go to the beginning) I am thinking this would work because it will restore the navigation state when the authentication state has been set correctly. I am also thinking having it done this way will unload all the authentication screen related components from memory including the navigation since it will be no longer be relevant. I am also thinking the typings would be simplified because the authenticated and non-authenticate won't be intermingled.

  • Redo what was recommended in React Navigation authentication flow because the hacks I did was when we were still in React Navigation 4 and it's now React Navigation 6 and it may work as is.

Are there any other approach I should consider?

Archimedes Trajano
  • 35,625
  • 19
  • 175
  • 265

0 Answers0