|
1 | 1 | --- |
2 | 2 | id: navigator-comparison |
3 | | -title: Navigator Comparison |
| 3 | +title: Navigation |
4 | 4 | layout: docs |
5 | 5 | category: Guides |
6 | 6 | permalink: docs/navigator-comparison.html |
7 | 7 | next: performance |
8 | 8 | --- |
9 | 9 |
|
10 | | -The differences between [Navigator](docs/navigator.html) |
11 | | -and [NavigatorIOS](docs/navigatorios.html) are a common |
12 | | -source of confusion for newcomers. |
13 | | - |
14 | | -Both `Navigator` and `NavigatorIOS` are components that allow you to |
15 | | -manage the navigation in your app between various "scenes" (another word |
16 | | -for screens). They manage a route stack and allow you to pop, push, and |
17 | | -replace states. In this way, [they are similar to the html5 history |
18 | | -API](https://developer.mozilla.org/en-US/docs/Web/Guide/API/DOM/Manipulating_the_browser_history). |
19 | | -The primary distinction between the two is that `NavigatorIOS` leverages |
20 | | -the iOS |
21 | | -[UINavigationController](https://developer.apple.com/library/ios/documentation/UIKit/Reference/UINavigationController_Class/) |
22 | | -class, and `Navigator` re-implements that functionality entirely in |
23 | | -JavaScript as a React component. A corollary of this is that `Navigator` |
24 | | -will be compatible with Android and iOS, whereas `NavigatorIOS` will |
25 | | -only work on the one platform. Below is an itemized list of differences |
26 | | -between the two. |
| 10 | +Mobile apps rarely consist of just one screen or scene. 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 | +Navigators in React Native allow you to push and pop scenes in a master/detail stack, or to pop up modal scenes. Navigators handle the transitions between scenes, and also maintain the navigational state of your application. |
| 13 | + |
| 14 | +If you are just getting started with React Native, you will probably want to start with the `Navigator` component. |
27 | 15 |
|
28 | 16 | ## Navigator |
29 | 17 |
|
30 | | -- Extensive API makes it completely customizable from JavaScript. |
31 | | -- Under active development from the React Native team. |
32 | | -- Written in JavaScript. |
33 | | -- Works on iOS and Android. |
34 | | -- Includes a simple navigation bar component similar to the default `NavigatorIOS` bar: `Navigator.NavigationBar`, and another with breadcrumbs called `Navigator.BreadcrumbNavigationBar`. See the UIExplorer demo to try them out and see how to use them. |
35 | | - - Currently animations are good and improving, but they are still less refined than Apple's, which you get from `NavigatorIOS`. |
36 | | -- You can provide your own navigation bar by passing it through the `navigationBar` prop. |
| 18 | +`Navigator` is a cross-platform implementation of a navigation stack, so it works on both iOS and Android. It is easy to customize and includes simple navigation bars. |
| 19 | + |
| 20 | +```js |
| 21 | +<Navigator |
| 22 | + initialRoute={{ title: 'My Initial Scene', index: 0}} |
| 23 | + renderScene={(route, navigator) => { |
| 24 | + // We'll get to this function soon. |
| 25 | + }} |
| 26 | +/> |
| 27 | +``` |
| 28 | + |
| 29 | +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 the `renderScene` function needs to render a scene. |
| 30 | + |
| 31 | +The `push` and `pop` functions provided by Navigator can be used to push and pop routes into the navigation stack. A more complete example that demonstrates the pushing and popping of routes could therefore look something like this: |
| 32 | + |
| 33 | +```js |
| 34 | +class MyScene extends Component { |
| 35 | + static propTypes = { |
| 36 | + title: PropTypes.string.isRequired, |
| 37 | + onForward: PropTypes.func.isRequired, |
| 38 | + onBack: PropTypes.func.isRequired, |
| 39 | + } |
| 40 | + render() { |
| 41 | + return ( |
| 42 | + <View> |
| 43 | + <Text>Current Scene: { this.props.title }</Text> |
| 44 | + <TouchableHighlight onPress={this.props.onForward}> |
| 45 | + <Text>Tap me to load the next scene</Text> |
| 46 | + </TouchableHighlight> |
| 47 | + <TouchableHighlight onPress={this.props.onBack}> |
| 48 | + <Text>Tap me to go back</Text> |
| 49 | + </TouchableHighlight> |
| 50 | + </View> |
| 51 | + ) |
| 52 | + } |
| 53 | +} |
| 54 | + |
| 55 | +class SimpleNavigationApp extends Component { |
| 56 | + render() { |
| 57 | + return ( |
| 58 | + <Navigator |
| 59 | + initialRoute={{ title: 'My Initial Scene', index: 0 }} |
| 60 | + renderScene={(route, navigator) => |
| 61 | + <MyScene |
| 62 | + title={route.title} |
| 63 | + onForward={ () => { |
| 64 | + const nextIndex = route.index + 1; |
| 65 | + navigator.push({ |
| 66 | + title: 'Scene ' + nextIndex, |
| 67 | + index: nextIndex, |
| 68 | + }); |
| 69 | + }} |
| 70 | + onBack={() => { |
| 71 | + if (route.index > 0) { |
| 72 | + navigator.pop(); |
| 73 | + } |
| 74 | + }} |
| 75 | + /> |
| 76 | + } |
| 77 | + /> |
| 78 | + ) |
| 79 | + } |
| 80 | +} |
| 81 | +``` |
| 82 | + |
| 83 | +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. |
| 84 | + |
| 85 | +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. Check out the [Navigator API reference](docs/navigator.html) to learn more. |
37 | 86 |
|
38 | 87 | ## NavigatorIOS |
39 | 88 |
|
40 | | -- Small, limited API makes it much less customizable than `Navigator` in its current form. |
41 | | -- Development belongs to open-source community - not used by the React Native team on their apps. |
42 | | - - A result of this is that there is currently a backlog of unresolved bugs, nobody who uses this has stepped up to take ownership for it yet. |
43 | | - - You may find an alternative in the community project [react-native-navigation](https://github.com/wix/react-native-navigation) which replaces `NavigatorIOS`. |
44 | | -- Wraps UIKit, so it works exactly the same as it would on another native app. Lives in Objective-C and JavaScript. |
45 | | - - Consequently, you get the animations and behavior that Apple has developed. |
46 | | -- iOS only. |
47 | | -- Includes a navigation bar by default; this navigation bar is not a React Native view component and the style can only be slightly modified. |
| 89 | +If you are targeting iOS only, you may also want to consider using `NavigatorIOS`. It looks and feels just like `UINavigationController`, because it is actually built on top of it. |
| 90 | + |
| 91 | +```js |
| 92 | +<NavigatorIOS |
| 93 | + initialRoute={{ |
| 94 | + component: MyScene, |
| 95 | + title: 'My Initial Scene', |
| 96 | + passProps: { myProp: 'foo' }, |
| 97 | + }} |
| 98 | +/> |
| 99 | +``` |
| 100 | + |
| 101 | +Just like Navigator, it it 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. |
| 102 | + |
| 103 | +Check out the [NavigatorIOS reference docs](docs/navigatorios.html) to learn more about this component. |
| 104 | + |
| 105 | +```js |
| 106 | +class MyScene extends Component { |
| 107 | + static propTypes = { |
| 108 | + title: PropTypes.string.isRequired, |
| 109 | + navigator: PropTypes.object.isRequired, |
| 110 | + } |
| 111 | + |
| 112 | + constructor(props, context) { |
| 113 | + super(props, context); |
| 114 | + this._onForward = this._onForward.bind(this); |
| 115 | + this._onBack = this._onBack.bind(this); |
| 116 | + } |
| 117 | + |
| 118 | + _onForward() { |
| 119 | + this.props.navigator.push({ |
| 120 | + title: 'Scene ' + nextIndex, |
| 121 | + }); |
| 122 | + } |
| 123 | + |
| 124 | + _onBack() { |
| 125 | + this.props.navigator.pop(); |
| 126 | + } |
| 127 | + |
| 128 | + render() { |
| 129 | + return ( |
| 130 | + <View> |
| 131 | + <Text>Current Scene: { this.props.title }</Text> |
| 132 | + <TouchableHighlight onPress={this._onForward}> |
| 133 | + <Text>Tap me to load the next scene</Text> |
| 134 | + </TouchableHighlight> |
| 135 | + <TouchableHighlight onPress={this._onBack}> |
| 136 | + <Text>Tap me to go back</Text> |
| 137 | + </TouchableHighlight> |
| 138 | + </View> |
| 139 | + ) |
| 140 | + } |
| 141 | +} |
| 142 | + |
| 143 | +class NavigatorIOSApp extends Component { |
| 144 | + render() { |
| 145 | + return ( |
| 146 | + <NavigatorIOS |
| 147 | + initialRoute={{ |
| 148 | + component: MyScene, |
| 149 | + title: 'My Initial Scene', |
| 150 | + index: 0 |
| 151 | + }} |
| 152 | + renderScene={ (route, navigator) => |
| 153 | + <MyScene title={route.title} /> |
| 154 | + } |
| 155 | + /> |
| 156 | + ) |
| 157 | + } |
| 158 | +} |
| 159 | +``` |
| 160 | + |
| 161 | +> 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. |
| 162 | +
|
| 163 | +## Navigation (Experimental) |
48 | 164 |
|
49 | | -For most non-trivial apps, you will want to use `Navigator` - it won't be long before you run into issues when trying to do anything complex with `NavigatorIOS`. |
| 165 | +If you are looking for a more powerful navigation API, check out [NavigationExperimental](https://github.com/facebook/react-native/tree/master/Examples/UIExplorer/NavigationExperimental). It provides greater customization over your transitions, uses single-directional data flow using reducers to manipulate state at a top-level object, and offloads transition animations to the GPU. |
0 commit comments