In this final example, you'll build an app that displays the user's progress through a predefined number of steps. For example, it might make sense to split a form into several logical sections and organize them in such a way that as the user completes one section, they move to the next step. A progress bar would be helpful feedback for the user.
You'll insert a progress bar into the navigation bar, just below the title, so that the user knows how far they've gone and how far is left to go. You'll also reuse the ProgressBar component that you implemented earlier in this chapter.
Let's take a look at the result first. There are four screens in this app that the user can navigate to. Here's what the first page (scene) looks like:

The progress bar below the title reflects the fact that the user is 25% through the navigation. Let's see what the third screen looks like:

The progress is updated to reflect where the user is in the route stack. Let's take a look at the App component:
import React from 'react';
import { createStackNavigator } from 'react-navigation';
import First from './First';
import Second from './Second';
import Third from './Third';
import Fourth from './Fourth';
const routes = [First, Second, Third, Fourth];
export default createStackNavigator(
routes.reduce(
(result, route) => ({
...result,
[route.name]: route
}),
{}
),
{
initialRouteName: 'First',
initialRouteParams: {
progress: route =>
(routes.map(r => r.name).indexOf(route) + 1) / routes.length
}
}
);
This app has four screens. The components that render each of these screens is stored in the routes constant, which is then used to configure the stack navigator using createStackNavigator(). The reason for creating the routes array is so that it can be used by the progress() function that is passed to the initial route (First) as a route parameter. This function takes the current route name as an argument and looks up its index position in routes. For example, Second is in the number 2 position (index of 1 + 1) and the length of the array is 4. This will set the progress bar to 50%.
Let's see how the progress function is used by the First component:
import React from 'react';
import { View, Text } from 'react-native';
import styles from './styles';
import ProgressBar from './ProgressBar';
const First = () => (
<View style={styles.container}>
<Text style={styles.content}>First Content</Text>
</View>
);
First.navigationOptions = ({ navigation }) => ({
headerTitle: (
<View style={styles.progress}>
<Text style={styles.title}>First</Text>
<ProgressBar
label={false}
progress={navigation.state.params.progress(
navigation.state.routeName
)}
/>
</View>
),
headerLeft: (
<Text
onPress={() =>
navigation.navigate('Fourth', navigation.state.params)
}
>
Fourth
</Text>
),
headerRight: (
<Text
onPress={() =>
navigation.navigate('Second', navigation.state.params)
}
>
Second
</Text>
)
});
export default First;
The function is accessed as navigation.state.params.progress(). It's passed the value of navigation.state.routeName to get the progress value for the current page. Also, the calls to navigation.navigate() have to pass navigation.state.params so that the progress() function is available to the screen. If you don't do this, then progress() will only be available to the first screen because it's set using the initialRouteParams option within the App component.