Skip to content

Commit 7d3fbbd

Browse files
hramosFacebook Github Bot 9
authored andcommitted
Introduce navigators in the tutorial
Summary: Adds a new section to the tutorial. Covers the basics of scenes and navigators. The navigator comparison doc has been moved to docs/navigation.html in this PR. ![navigators](https://cloud.githubusercontent.com/assets/165856/16505919/37459e3a-3ed4-11e6-87e9-5fa7e6f792d3.png) Closes #8515 Differential Revision: D3507325 Pulled By: caabernathy fbshipit-source-id: e9ee5b2572868189af198cdf461b2728dfa84f9e
1 parent ccd608a commit 7d3fbbd

File tree

4 files changed

+199
-107
lines changed

4 files changed

+199
-107
lines changed

docs/JavaScriptEnvironment.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ title: JavaScript Environment
44
layout: docs
55
category: Guides
66
permalink: docs/javascript-environment.html
7-
next: navigator-comparison
7+
next: navigation
88
---
99

1010
## JavaScript Runtime

docs/NavigatorComparison.md renamed to docs/Navigation.md

Lines changed: 26 additions & 102 deletions
Original file line numberDiff line numberDiff line change
@@ -1,107 +1,31 @@
11
---
2-
id: navigator-comparison
2+
id: navigation
33
title: Navigation
44
layout: docs
55
category: Guides
6-
permalink: docs/navigator-comparison.html
6+
permalink: docs/navigation.html
77
next: performance
88
---
99

10-
Mobile apps rarely consist of just one scene (another word for screen). As soon as you add a second scene to your app, you will have to take into consideration how the user will navigate from one scene to the other.
11-
12-
You can use navigators to transition between multiple scenes. These transitions can be typical side-to-side animations down a master/detail stack, or vertical modal popups.
10+
This guide covers the various navigation components available in React Native. If you are just getting started with navigation, you will probably want to use `Navigator`. If you are only targeting iOS and would like to stick to the native look and feel, check out `NavigatorIOS`. If you are looking for greater control over your navigation stack, you can't go wrong with `NavigationExperimental`.
1311

1412
## Navigator
1513

16-
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.
14+
`Navigator` provides a JavaScript implementation of a navigation stack, so it works on both iOS and Android and is easy to customize. This is the same component you used to build your first navigation stack in the [navigators tutorial](docs/navigators.html).
1715

1816
![](img/NavigationStack-Navigator.gif)
1917

20-
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. A basic `Navigator` implementation may look like this:
21-
22-
```js
23-
<Navigator
24-
initialRoute={{ title: 'My Initial Scene', index: 0 }}
25-
renderScene={(route, navigator) => {
26-
<MyScene title={route.title} />
27-
}}
28-
/>
29-
```
30-
31-
The above example will display a single scene, but in order to push a new scene onto screen 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. They can be used, as you may have realized, to push and pop routes into your navigation stack.
32-
33-
A more complete example that demonstrates the pushing and popping of routes could therefore look something like this:
18+
`Navigator` can easily be adapted to render different components based on the current route in its `renderScene` function. It will transition new scenes onto the screen by sliding in from the right by default, but you can control this behavior by using the `configureScene` function. You can also configure a navigation bar through the `navigationBar` prop.
3419

35-
```js
36-
import React, { Component, PropTypes } from 'react';
37-
import { Navigator, Text, TouchableHighlight, View } from 'react-native';
38-
39-
export default class SimpleNavigationApp extends Component {
40-
render() {
41-
return (
42-
<Navigator
43-
initialRoute={{ title: 'My Initial Scene', index: 0 }}
44-
renderScene={(route, navigator) =>
45-
<MyScene
46-
title={route.title}
47-
48-
// Function to call when a new scene should be displayed
49-
onForward={ () => {
50-
const nextIndex = route.index + 1;
51-
navigator.push({
52-
title: 'Scene ' + nextIndex,
53-
index: nextIndex,
54-
});
55-
}}
56-
57-
// Function to call to go back to the previous scene
58-
onBack={() => {
59-
if (route.index > 0) {
60-
navigator.pop();
61-
}
62-
}}
63-
/>
64-
}
65-
/>
66-
)
67-
}
68-
}
69-
70-
class MyScene extends Component {
71-
static propTypes = {
72-
title: PropTypes.string.isRequired,
73-
onForward: PropTypes.func.isRequired,
74-
onBack: PropTypes.func.isRequired,
75-
}
76-
render() {
77-
return (
78-
<View>
79-
<Text>Current Scene: { this.props.title }</Text>
80-
<TouchableHighlight onPress={this.props.onForward}>
81-
<Text>Tap me to load the next scene</Text>
82-
</TouchableHighlight>
83-
<TouchableHighlight onPress={this.props.onBack}>
84-
<Text>Tap me to go back</Text>
85-
</TouchableHighlight>
86-
</View>
87-
)
88-
}
89-
}
90-
```
91-
92-
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.
93-
94-
While this is a very basic example, it can easily be adapted to render an entirely different component based on the route that is passed to the `renderScene` function. Navigator will push new scenes from the right by default, and you can control this behavior by using the `configureScene` function. You can also configure a navigation bar through the `navigationBar` prop.
95-
96-
Check out the [Navigator API reference](docs/navigator.html) for more code samples.
20+
Check out the [Navigator API reference](docs/navigator.html) for specific examples that cover each of these scenarios.
9721

9822
## NavigatorIOS
9923

10024
If you are targeting iOS only, you may also want to consider using [NavigatorIOS](docs/navigatorios.html). It looks and feels just like [`UINavigationController`](https://developer.apple.com/library/ios/documentation/UIKit/Reference/UINavigationController_Class/), because it is actually built on top of it.
10125

10226
![](img/NavigationStack-NavigatorIOS.gif)
10327

104-
```js
28+
```javascript
10529
<NavigatorIOS
10630
initialRoute={{
10731
component: MyScene,
@@ -111,13 +35,11 @@ If you are targeting iOS only, you may also want to consider using [NavigatorIOS
11135
/>
11236
```
11337

114-
Just like Navigator, NavigatorIOS uses routes to represent scenes, with some important differences. The actual component that will be rendered can be specified using the `component` key in the route, and any props that should be passed to this component can be specified in `passProps`. A "navigator" object is automatically passed as a prop to the component, allowing you to call `push` and `pop` as needed.
38+
Just like `Navigator`, `NavigatorIOS` uses routes to represent scenes, with some important differences. The actual component that will be rendered can be specified using the `component` key in the route, and any props that should be passed to this component can be specified in `passProps`. A "navigator" object is automatically passed as a prop to the component, allowing you to call `push` and `pop` as needed.
11539

116-
As NavigatorIOS leverages native UIKit navigation, it will automatically render a navigation bar with a back button and title.
40+
As `NavigatorIOS` leverages native UIKit navigation, it will automatically render a navigation bar with a back button and title.
11741

118-
Check out the [NavigatorIOS reference docs](docs/navigatorios.html) to learn more about this component.
119-
120-
```js
42+
```javascript
12143
import React, { Component, PropTypes } from 'react';
12244
import { NavigatorIOS, Text, TouchableHighlight, View } from 'react-native';
12345

@@ -165,23 +87,25 @@ class MyScene extends Component {
16587
}
16688
```
16789

90+
Check out the [`NavigatorIOS` reference docs](docs/navigatorios.html) to learn more about this component.
91+
16892
> You may also want to check out [react-native-navigation](https://github.com/wix/react-native-navigation), a component that aims to provide native navigation on both iOS and Android.
16993
17094
## NavigationExperimental
17195

172-
Navigator and NavigatorIOS are both stateful components. If your app has multiple of these, it can become tricky to coordinate navigation transitions between them. NavigationExperimental provides a different approach to navigation, allowing any view to act as a navigation view and using reducers to manipulate state at a top-level object. It is bleeding edge as the name implies, but you might want to check it out if you are craving greater control over your app's navigation.
96+
`Navigator` and `NavigatorIOS` are both stateful components. If your app has multiple of these, it can become tricky to coordinate navigation transitions between them. NavigationExperimental provides a different approach to navigation, allowing any view to act as a navigation view and using reducers to manipulate state at a top-level object. It is bleeding edge as the name implies, but you might want to check it out if you are craving greater control over your app's navigation.
17397

174-
```js
98+
```javascript
17599
<NavigationCardStack
176100
onNavigateBack={onPopRouteFunc}
177101
navigationState={myNavigationState}
178102
renderScene={renderSceneFun}
179103
/>
180104
```
181105

182-
You can import NavigationExperimental like any other component in React Native. Once you have that, you can deconstruct any additional components from NavigationExperimental that you may find useful. Since I am feeling like building navigation stacks today, I'll go ahead and pick out NavigationCardStack and NavigationStateUtils.
106+
You can import `NavigationExperimental` like any other component in React Native. Once you have that, you can deconstruct any additional components from `NavigationExperimental` that you may find useful. Since I am feeling like building navigation stacks today, I'll go ahead and pick out `NavigationCardStack` and `NavigationStateUtils`.
183107

184-
```js
108+
```javascript
185109
import React, { Component } from 'react';
186110
import { NavigationExperimental } from 'react-native';
187111

@@ -191,13 +115,13 @@ const {
191115
} = NavigationExperimental;
192116
```
193117

194-
As I said earlier, NavigationExperimental takes a different approach than Navigator and NavigatorIOS. Using it to build a navigation stack requires a few more steps than the stateful components, but the payoff is worth it.
118+
As I said earlier, `NavigationExperimental` takes a different approach than `Navigator` and `NavigatorIOS`. Using it to build a navigation stack requires a few more steps than the stateful components, but the payoff is worth it.
195119

196120
### Step 1. Define Initial State and Top Level Component
197121

198122
Create a new component for your application. This will be the top-level object, so we will define the initial state here. The navigation state will be defined in the `navigationState` key, where we define our initial route:
199123

200-
```js
124+
```javascript
201125
class BleedingEdgeApplication extends Component {
202126
constructor(props, context) {
203127
super(props, context);
@@ -236,7 +160,7 @@ NavigationExperimental comes built-in with a some useful reducers, and they are
236160

237161
We can use them to write our `_onNavigationChange` function which, given a "push" or "pop" action, will reduce the state accordingly.
238162

239-
```js
163+
```javascript
240164
_onNavigationChange(type) {
241165
// Extract the navigationState from the current state:
242166
let {navigationState} = this.state;
@@ -270,13 +194,13 @@ _onNavigationChange(type) {
270194

271195
Cool. I'm getting the hang of this. This is the heart of NavigationExperimental. We are only handling two actions here, but a more complex application could also take into account a "back" action (e.g. Android back button), as well as handle the transition between several tabs in a tabbed application.
272196

273-
I am still missing the initial scene that will be rendered (as well as the actual navigator that will wrap it, but lets not get ahead of ourselves).
197+
I am still missing the initial scene that will be rendered (as well as the actual navigator that will wrap it, but let's not get ahead of ourselves).
274198

275199
### Step 3. Define Scenes
276200

277201
First I want to define a Row component out of convenience. It displays some text and can call some function when pressed.
278202

279-
```js
203+
```javascript
280204
class TappableRow extends Component {
281205
render() {
282206
return (
@@ -295,7 +219,7 @@ class TappableRow extends Component {
295219

296220
Now I will define my actual scene. It uses a scroll view to display a vertical list of items. The first row displays the current route's key, and two more rows will call our theoretical navigator's push and pop functions.
297221

298-
```js
222+
```javascript
299223
class MyVeryComplexScene extends Component {
300224
render() {
301225
return (
@@ -321,7 +245,7 @@ class MyVeryComplexScene extends Component {
321245

322246
Now that I have defined the state and a function to manage it, I think I can go ahead and create a proper navigator component now. While I'm at it, I'll render my scene after configuring it with the current route's props.
323247

324-
```js
248+
```javascript
325249
class MyVerySimpleNavigator extends Component {
326250

327251
// This sets up the methods (e.g. Pop, Push) for navigation.
@@ -364,9 +288,9 @@ class MyVerySimpleNavigator extends Component {
364288
}
365289
```
366290

367-
That's it -- so close to the finish line I can smell it. Lets plug our new navigator into our top-level component:
291+
That's it -- so close to the finish line I can smell it. Let's plug our new navigator into our top-level component:
368292

369-
```js
293+
```javascript
370294
class BleedingEdgeApplication extends Component {
371295

372296
// constructor and other methods omitted for clarity
@@ -389,7 +313,7 @@ We're done! Bask in the glory of NavigationExperimental.
389313

390314
(Oh yes, sorry about that -- here's our missing imports and styles.)
391315

392-
```js
316+
```javascript
393317
import { NavigationExperimental, PixelRatio, ScrollView, StyleSheet, Text, TouchableHighlight } from 'react-native';
394318

395319
const styles = StyleSheet.create({

0 commit comments

Comments
 (0)