Pop Navigation

Popping

Because the Navigation router pushes scenes using the native APIs, the user can pop them via the Android back button or swiping/pressing back on iOS. You can also programmatically pop scenes by calling the navigateBack function on the StateNavigator. The number you pass in indicates the number of scenes to pop. In our email example, we can add a button to the 'compose' scene that returns the user to the inbox.

import {NavigationContext} from 'navigation-react';

var Compose = () => (
  <NavigationContext.Consumer>
    {({stateNavigator}) => (
      <TouchableHighlight
        onPress={() => {
          stateNavigator.navigateBack(1);
        }}>
        <Text>Back to Inbox</Text>
      </TouchableHighlight>
    )}
  </NavigationContext.Consumer>
);

Popping to Top

The Navigation router is the only React Native router that navigates natively on Android and iOS where you can interrogate the stack in JavaScript. You recall that the Navigation router drops a breadcrumb at each visited scene, just like the fairy-tale characters Hansel and Gretel. The stack of visited scenes is represented in JavaScript as an array of breadcrumbs. Each crumb corresponds to a visited scene and holds the State and navigation data associated with it.

Let's use this array of crumbs to make the 'Back to Inbox' button work regardless of the route the user takes to get to the 'compose' scene. For example, if the user presses the 'Compose Mail' button after opening an email, then popping one scene off the stack goes back to the open email instead of the inbox. We ensure the 'Back to Inbox' button always pops to the top of the stack by navigating back the length of the crumbs array.

var {crumbs} = stateNavigator.stateContext;
stateNavigator.navigateBack(crumbs.length);

Popping when Pushing

By default, each navigation adds one to the size of the stack. You can change this behaviour by attaching a truncateCrumbTrail function to a State. During a navigation, the Navigation router calls this function on the destination State. It passes in the provisional stack, as an array of crumbs, and you return the modified stack. Removing a crumb from the array pops the corresponding scene from the stack.

In our example, we can add an 'Expand' button to the 'mail' scene so the user can view the full email conversation. On click, we navigate to the 'mail' scene again and pass an 'expand' boolean in navigation data. We must pop the scene showing the collapsed email from the stack so that navigating back still returns the user to their inbox. Put another way, we must prevent consecutive occurrences of the mail State appearing in the crumbs array.

mail.truncateCrumbTrail = function(state, data, crumbs) {
  var latestCrumb = crumbs[crumbs.length - 1];
  return latestCrumb.state === state ? crumbs.slice(0, -1) : crumbs;
};