|
| 1 | +--- |
| 2 | +id: navigation |
| 3 | +title: Navigation |
| 4 | +layout: docs |
| 5 | +category: Guides |
| 6 | +permalink: docs/navigation.html |
| 7 | +next: navigator-comparison |
| 8 | +--- |
| 9 | + |
| 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. |
| 15 | + |
| 16 | +## Navigator |
| 17 | + |
| 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. |
| 86 | + |
| 87 | +## NavigatorIOS |
| 88 | + |
| 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) |
| 164 | + |
| 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