expo / ex-navigation

Route-centric navigation for React Native
997 stars 201 forks source link

Push / pop on root StackNavigation with TabNavigation as children results in incorrect currentNavigatorUID #433

Open jordanmkoncz opened 7 years ago

jordanmkoncz commented 7 years ago

I'm having an issue where navigating through my navigation hierarchy leads to currentNavigatorUID in my Redux store becoming incorrect and inconsistent with what the user is actually seeing on their screen.

In my hierarchy, at the top level is a StackNavigation (navigatorUID="rootStackNavigation"). Below this is two possible children, TabNavigation (navigatorUID="tabNavigationA") and TabNavigation (navigatorUID="tabNavigationB"). Below tabNavigationA is a StackNavigation (navigatorUID="stackNavigationChildA"). Below tabNavigationB is a StackNavigation (navigatorUID="stackNavigationChildB").

On load, the initial hierarchy is rootStackNavigation -> tabNavigationA -> stackNavigationChildA. From there the user can navigate to tabNavigationB, which happens by calling navigation.getNavigator('rootStackNavigation').push(Router.getRoute('TabScreenB'));, and this automatically loads tabNavigationB with stackNavigationChildB as a child. Up to this point everything is working as expected, and the current state is currentNavigatorUID === 'stackNavigationChildB';

The issue happens when the user taps a button to return to tabNavigationA. This makes a call navigation.getNavigator('rootStackNavigation').pop(), which has a very unexpected result. The following Redux actions get dispatched.

First:

{
  type: 'EX_NAVIGATION.REMOVE_NAVIGATOR',
  navigatorUID: 'tabNavigationB'
}

Which results in the state currentNavigatorUID === 'stackNavigationChildA';

Second:

{
  type: 'EX_NAVIGATION.REMOVE_NAVIGATOR',
  navigatorUID: 'stackNavigationChildB'
}

Which results in the state currentNavigatorUID === 'tabNavigationB';

In the app, the user is now looking at stackNavigationChildA (which is contained within tabNavigationA), which is correct, however currentNavigatorUID is incorrect, it is now tabNavigationB when it should be stackNavigationChildA.

I believe this is happening because the action to remove the stackNavigationChildB navigator is happening after the action to remove the tabNavigationB navigator (which is its parent), when it should be the other way around. So the action to remove tabNavigationB happens and the resulting state is correct at this point, but then the action to remove stackNavigationChildB happens and ExNavigation sees that tabNavigationB is the parent of stackNavigationChildB, so it sets currentNavigatorUID to tabNavigationB.

This problem is causing issues with me using functionality like NavigationActions.showLocalAlert(), where I need to be able to pass in the correct currentNavigatorUID so that the alert is shown in the right navigator, but since currentNavigatorUID becomes incorrect and inconsistent with what the user is actually seeing on their screen, if I try to show an alert they won't see it since it's shown in a navigator that is no longer visible.

nehvaleem commented 7 years ago

yeah, I am facing same issue

jordanmkoncz commented 7 years ago

Anyone been able to look into this? I'm now running into another problem because of this issue, where I need to use currentNavigatorUID to determine the current screen name for analytics purposes, but again can't do this reliably since currentNavigatorUID becomes incorrect.

alexprice1 commented 7 years ago

bump :/