One thing we learnt from using React Navigation with React Native is how hard it is to go back properly in our nested stack navigators.
For example, let's take this navigator router: it has a ++code class="markup--code markup--p-code">StackNavigator++/code> as its root navigator and other nested navigators.
++pre>++code class="language-javascript">const RootNavigator = StackNavigator(
{
home: {
screen: DrawerNavigator(
{
home: {
screen: Pages.Home,
},
},
{
initialRouteName: 'home',
}
),
path: 'home',
},
authentication: {
screen: StackNavigator({
login: {
screen: Pages.Login,
},
signin: {
...
},
signup: {
...
},
}),
},
},
{
initialRouteName: 'home',
}
);++/code>++/pre>
While you navigate in your application, at some point you might want to go back to the home page and clear all your navigation stack.
For example, if you are located on the login page, in your redux inspector, you would see:
++pre>++code>++code class="markup--code markup--pre-code">nav(pin)
index(pin): 1
?routes(pin)
?0(pin)
type(pin): "Navigation/NAVIGATE"
routeName(pin): "home"
?routes(pin): [{?}, {?}, {?}]
index(pin): 0
key(pin): "id-1234567890123-3"
?1(pin)
index(pin): 0
?routes(pin)
?0(pin)
routeName(pin): "login"
key(pin): "Init-id-1234567890123-5"
key(pin): "id-1234567890123-6"
routeName(pin): "authentication"++/code>++/pre>
In order to go back to the home page, you shouldn't use the method ++code class="markup--code markup--p-code">back++/code>of react-navigation repeatedly as it is suggested at the end of this thread for example. Instead, use ++code class="markup--code markup--p-code">reset++/code> with a ++code class="markup--code markup--p-code">key: null++/code> to ask react-navigation to reset the root navigator.
++table style="border-color: #ff0000;" border="1" cellpadding="5">++tbody>++tr>++td style="border-color: #ff0000; padding: 10px; border-width: 1px;">
Don't: this might be OK in dev environnement, but this will certainly make your bundled application crash in production environnement
++pre>++code>++code class="markup--code markup--pre-code">yield put(NavigationActions.back({ key: null }));
yield put(NavigationActions.back({ key: null }));
yield put(NavigationActions.back({ key: null }));
yield put(NavigationActions.back({ key: null }));++/code>++/pre>++/td>++/tr>++/tbody>++/table>
++table style="width: 100%; border-color: #309e15;" border="1" cellpadding="5">++tbody>++tr>++td style="border-color: #429e10; padding: 10px;">
Do: properly reset the navigator
++pre>++code>++code class="markup--code markup--pre-code">yield put(
NavigationActions.reset({
key: null,
index: 0,
actions: [NavigationActions.navigate({ routeName: 'home' })],
})
);++/code>++/pre>++/td>++/tr>++/tbody>++/table>
How does ++code class="markup--code markup--p-code">reset++/code> works ?
For example?
++pre>++code>++code class="markup--code markup--pre-code">NavigationActions.reset({
index: 1,
actions: [
NavigationActions.navigate({ routeName: 'home' }),
NavigationActions.navigate({ routeName: 'settings' })
]
});++/code>++/pre>
? will replace your current navigator state by a state with the ++code class="markup--code markup--p-code">'settings'++/code> route on top of the ++code class="markup--code markup--p-code">'home'++/code> route; and the active route is the one which ++code class="markup--code markup--p-code">index++/code> is ++code class="markup--code markup--p-code">1++/code> i.e. the ++code class="markup--code markup--p-code">'settings'++/code> route.
Finally, in order to use properly React Navigation API, dispatch only one action at a time.