6.4 KiB
id | title | layout | category | permalink | next | previous |
---|---|---|---|---|---|---|
using-navigators | Using Navigators | docs | The Basics | docs/using-navigators.html | more-resources | networking |
Mobile apps rarely consist of just one screen. As soon as you add a second screen to your app, you will have to take into consideration how the user will navigate from one screen to the other.
You can use navigators to transition between multiple screens. These transitions can be typical side-to-side animations down a master/detail stack, or vertical modal popups.
Navigator
React Native has several built-in navigation components, but for your first app you will probably want to use Navigator
. It provides a JavaScript implementation of a navigation stack, so it works on both iOS and Android and is easy to customize.
Working with Scenes
At this point you should feel comfortable rendering all sorts of components in your app, be it a simple View
with Text
inside, or a ScrollView
with a list of Image
s. Together, these components make up a scene (another word for screen) in your app.
A scene is nothing other than a React component that is typically rendered full screen. This is in contrast to a Text
, an Image
, or even a custom SpinningBeachball
component that is meant to be rendered as part of a screen. You may have already used one without realizing it - the "HelloWorldApp", the "FlexDirectionBasics", and the "ListViewBasics" components covered earlier in the tutorial are all examples of scenes.
For simplicity's sake, let's define a simple scene that displays a bit of text. We will come back to this scene later as we add navigation to our app. Create a new file called "MyScene.js" with the following contents:
import React, { Component } from 'react';
import { View, Text } from 'react-native';
export default class MyScene extends Component {
static get defaultProps() {
return {
title: 'MyScene'
};
}
render() {
return (
<View>
<Text>Hi! My name is {this.props.title}.</Text>
</View>
)
}
}
Notice the export default
in front of the component declaration. This will export the component, and in turn allow other components to import it later on, like so:
import React, { Component } from 'react';
import { AppRegistry } from 'react-native';
import MyScene from './MyScene';
class YoDawgApp extends Component {
render() {
return (
<MyScene />
)
}
}
AppRegistry.registerComponent('YoDawgApp', () => YoDawgApp);
We now have a simple app that renders your scene and nothing else. In this case, MyScene
is a simple example of a reusable React component.
Using Navigator
Enough about scenes, let's start navigating. We will start by rendering a Navigator
, and then let the Navigator
render the scene for you by passing in your own render function to its renderScene
prop.
render() {
return (
<Navigator
initialRoute={{ title: 'My Initial Scene', index: 0 }}
renderScene={(route, navigator) => {
<MyScene title={route.title} />
}}
/>
);
}
Something you will encounter a lot when dealing with navigation is the concept of routes. A route is an object that contains information about a scene. It is used to provide all the context that the navigator's renderScene
function needs to render a scene. It can have any number of keys to help distinguish your scene, and I happened to pick a single title
key for the above example.
Pushing scenes onto the stack
In order to transition to a new scene, you will need to learn about push
and pop
. These two methods are provided by the navigator
object that is passed to your renderScene
function above. They can be used, as you may have realized, to push and pop routes into your navigation stack.
navigator.push({
title: 'Next Scene',
index: 1,
});
navigator.pop();
A more complete example that demonstrates the pushing and popping of routes could therefore look something like this:
import React, { Component, PropTypes } from 'react';
import { Navigator, Text, TouchableHighlight, View } from 'react-native';
export default class SimpleNavigationApp extends Component {
render() {
return (
<Navigator
initialRoute={{ title: 'My Initial Scene', index: 0 }}
renderScene={(route, navigator) =>
<MyScene
title={route.title}
// Function to call when a new scene should be displayed
onForward={ () => {
const nextIndex = route.index + 1;
navigator.push({
title: 'Scene ' + nextIndex,
index: nextIndex,
});
}}
// Function to call to go back to the previous scene
onBack={() => {
if (route.index > 0) {
navigator.pop();
}
}}
/>
}
/>
)
}
}
class MyScene extends Component {
static propTypes = {
title: PropTypes.string.isRequired,
onForward: PropTypes.func.isRequired,
onBack: PropTypes.func.isRequired,
}
render() {
return (
<View>
<Text>Current Scene: { this.props.title }</Text>
<TouchableHighlight onPress={this.props.onForward}>
<Text>Tap me to load the next scene</Text>
</TouchableHighlight>
<TouchableHighlight onPress={this.props.onBack}>
<Text>Tap me to go back</Text>
</TouchableHighlight>
</View>
)
}
}
In this example, the MyScene
component is passed the title of the current route via the title
prop. It displays two tappable components that call the onForward
and onBack
functions passed through its props, which in turn will call navigator.push()
and navigator.pop()
as needed.
Check out the Navigator API reference for more Navigator
code samples, or read through the Navigation guide for other examples of what you can do with navigators.
High Five!
If you've gotten here by reading linearly through the tutorial, then you are a pretty impressive human being. Congratulations. Next, you might want to check out all the cool stuff the community does with React Native.