Cool, so the rocket launcher was your first app with multiple “pages”. But simply using manually-controlled component state to manage location state definitely doesn’t scale. Let’s look at a better way to handle navigation.
The finest solution to navigation currently exists as an independent library, react-navigation
. We’ll install and use this library below.
Build an app that provides details about some popular SXSW venues.
Here’s an example of what that could look like:
Feel free to make yours prettier! :-)
Install react-navigation
by running npm install react-navigation
(or yarn add react-navigation
if you have yarn installed).
Before you begin, replace the contents of your project’s App.js
file with the following:
import React from "react";
import {
Button,
Image,
ScrollView,
StyleSheet,
Text,
TouchableOpacity,
View
} from "react-native";
import { StackNavigator } from "react-navigation";
const venues = [
{
id: 1,
name: "Austin Convention Center",
address: "500 E Cesar Chavez",
imageUrl:
"https://res.cloudinary.com/simpleview/image/upload/c_fill,f_auto,h_240,q_75,w_300/v1/clients/austin/Austin_Convention_Center_Photo_Credit_Thomas_McConnell_Full_Usage_Permissions_5__7e33dc59-1b4c-4de9-9044-c9d18041cca9.jpg",
latitude: "30.263569",
longitude: "-97.739606"
},
{
id: 2,
name: "JW Marriott",
address: "110 E 2nd St",
imageUrl:
"https://wa2.jetcdn.com/photos/jw-marriott-austin/5vOE_FjZ/architecture-city-downtown-building.jpeg?w=780&h=520&dpr=1",
latitude: "30.264509",
longitude: "-97.743470"
},
{
id: 3,
name: "Westin Austin Downtown",
address: "310 E 5th St",
imageUrl:
"http://www.starwoodhotels.com/pub/media/3899/wes3899po.214266_md.jpg",
latitude: "30.266620",
longitude: "-97.740375"
},
{
id: 4,
name: "Hilton Austin Downtown",
address: "500 E 4th St",
imageUrl:
"http://momvoyage.hilton.com/wp-content/uploads/2014/10/Best-Downtown-Austin-Hotels-Hilton-Austin-e1413228104466-940x564.jpg",
latitude: "30.265259",
longitude: "-97.738290"
},
{
id: 5,
name: "The Driskill",
address: "604 Brazos St",
imageUrl:
"https://assets.hospitalityonline.com/photos/employers/258110/404068_l.jpg",
latitude: "30.268538",
longitude: "-97.741633"
}
];
class HomeScreen extends React.Component {
render() {
return (
<View style={styles.container}>
<Text style={styles.welcome}>Getting Around an App</Text>
<ScrollView contentContainerStyle={styles.centerContent}>
<Text style={styles.instructions}>
Using `react-navigation`, make an app{"\n"}
that lists the venue names in the `venues` array,{"\n"}
and allows the user to click to view more information.
</Text>
<Text style={styles.subtext}>See below for inspiration:</Text>
<Image
style={styles.targetImage}
source={{
uri:
"https://monosnap.com/file/GDpr0spLEoewjPiyyAbDC3fjirtL5D.png"
}}
/>
<Image
style={styles.targetImage}
source={{
uri:
"https://monosnap.com/file/R2M8LSTg1ghF7aMclFZXG2e2pTQKrn.png"
}}
/>
</ScrollView>
</View>
);
}
}
const RootStack = StackNavigator(
{
Home: {
screen: HomeScreen
}
},
{
initialRouteName: "Home"
}
);
export default class App extends React.Component {
render() {
return <RootStack />;
}
}
const styles = StyleSheet.create({
container: {
alignItems: "center",
backgroundColor: "#eee",
flex: 1,
justifyContent: "center"
},
centerContent: {
alignItems: "center"
},
welcome: {
fontSize: 20,
textAlign: "center",
margin: 10
},
instructions: {
textAlign: "center",
color: "#333333",
marginBottom: 10
},
subtext: {
fontSize: 14,
fontStyle: "italic"
},
targetImage: {
width: 150,
height: 300,
marginTop: 25
}
});
React Navigation is built around the concept of the navigation stack. You can think of this stack as similar to a browser’s history. As you visit a new page, you add the page to the top of the stack. When you go back, you simply pop the top page off of the stack and return to the page below it in line.
React Navigation provides a function, StackNavigator
, where you can define how the stack will be managed. Specifically, in this function you will define various routes to “Screen” components, as well as provide configuration like what screen the app should start on.
You’ll notice that we’ve already started the StackNavigator
functional call for you. You’ll need to add routes to this.
A route at its simplest is just a map from a name to a component class. Take for example:
Details: {
screen: DetailsScreen,
}
This would be a route named Details, that when pushed onto the stack would render a DetailsScreen
component.
Each screen component (whose component classes appear in your routes), receives a navigation
prop when it is rendered by React Navigation. This prop provides access to all navigation related information actions.
The most basic action you can perform is to navigate to a new route, that is push a new screen onto the navigation stack. this.props.navigation.navigate('Details')
This would cause an instance of the component class defined as the screen
for the Details
route to be rendered.
In addition to manually directing navigation to a certain screen, you can also perform actions on the stack like this.props.navigation.goBack()
. This pops the current screen off the stack and renders the previous screen.
The utility of these routes would be extremely limited if we were not able to pass data to them. For instance, you may wish to provide a venueId
to the DetailsScreen
to tell it which venue to showcase. Fortunately we can pass arbitrary data in the form of an object as a second argument when navigating like so: this.props.navigation.navigate('Details', { venueId: 42 })
. The data object will then be available in the screen component that is rendered via this.props.navigation.state.params
.
Full documentation for React Navigation can be found here: https://reactnavigation.org/docs/hello-react-navigation.html. Jump into the docs to see more examples of use, or to read up on the other functionality it can provide.
When you’re done, post a screenshot of your beautiful app to the #progress channel, then move on to Challenge 6.