# React Navigation 4.x Documentation
## Getting started
Source: https://reactnavigation.org/docs/4.x/getting-started
React Navigation is born from the React Native community's need for an extensible yet easy-to-use navigation solution written entirely in JavaScript (so you can read and understand all of the source), on top of powerful native primitives.
Before you commit to using React Navigation for your project, you might want to read the [anti-pitch](pitch.md) — it will help you to understand the tradeoffs that we have chosen along with the areas where we consider the library to be deficient currently.
## What to expect
If you're already familiar with React Native then you'll be able to get moving with React Navigation quickly! If not, you may want to read sections 1 to 4 (inclusive) of [React Native Express](http://reactnativeexpress.com/) first, then come back here when you're done.
What follows within the _Fundamentals_ section of this documentation is a tour of the most important aspects of React Navigation. It should cover enough for you to know how to build your typical small mobile application, and give you the background that you need to dive deeper into the more advanced parts of React Navigation.
## Start from a template
The easiest way to get running with `react-navigation` is to initialize a project using `expo-cli`. You can install this with `npm i -g expo-cli`.
- If you'd like to create a [managed React Native project](https://docs.expo.io/versions/latest/introduction/managed-vs-bare) then choose the `blank` template under the Managed workflow heading.
- If you'd like a [bare React Native project](https://docs.expo.io/versions/latest/introduction/managed-vs-bare/#bare-workflow), then choose `minimal` under the Bare workflow heading.
- In both cases you can pick the TypeScript version of the template if you prefer — React Navigation ships with TypeScript types.
Once the project is initialized, in the project directory run `npx expo install react-navigation react-native-gesture-handler react-native-reanimated react-native-screens`, and you're ready to go! You can now continue to ["Hello React Navigation"](hello-react-navigation.md) to start writing some code.
## Install into an existing project
Install the `react-navigation` package in your React Native project.
```bash npm2yarn
npm install react-navigation
```
React Navigation is made up of some core utilities and those are then used by navigators to create the navigation structure in your app. Don't worry too much about this for now, it'll become clear soon enough! To frontload the installation work, let's also install and configure dependencies used by most navigators, then we can move forward with starting to write some code.
The libraries we will install now are [`react-native-gesture-handler`](https://github.com/software-mansion/react-native-gesture-handler), [`react-native-reanimated`](https://github.com/software-mansion/react-native-reanimated), [`react-native-screens`](https://github.com/software-mansion/react-native-screens) and [`react-native-safe-area-context`](https://github.com/th3rdwave/react-native-safe-area-context). If you already have these libraries installed and at the latest version, you are done here! Otherwise, read on.
#### Installing dependencies into an Expo managed project
In your project directory, run:
```bash
npx expo install react-native-gesture-handler react-native-reanimated react-native-screens react-native-safe-area-context @react-native-community/masked-view
```
This will install versions of these libraries that are compatible.
You can now continue to ["Hello React Navigation"](hello-react-navigation.md) to start writing some code.
#### Installing dependencies into a bare React Native project
In your project directory, run:
```bash npm2yarn
npm install react-native-reanimated react-native-gesture-handler react-native-screens react-native-safe-area-context @react-native-community/masked-view
```
> Note: You might get warnings related to peer dependencies after installation. They are usually caused by incorrect version ranges specified in some packages. You can safely ignore most warnings as long as your app builds.
Next, we need to link these libraries. The steps depends on your React Native version:
- **React Native 0.60 and higher**
On newer versions of React Native, [linking is automatic](https://github.com/react-native-community/cli/blob/master/docs/autolinking.md).
If you're on a Mac and developing for iOS, you need to install pods to complete the linking. Make sure you have [Cocoapods](https://cocoapods.org/) installed. Then run:
```bash
cd ios; pod install; cd ..
```
- **React Native 0.59 and lower**
If you're on an older React Native version, you need to manually link the dependencies. To do that, run:
```bash
react-native link react-native-reanimated
react-native link react-native-gesture-handler
react-native link react-native-screens
react-native link react-native-safe-area-context
```
You also need to configure [jetifier](https://github.com/mikehardy/jetifier) to support dependencies using `androidx`:
```bash npm2yarn
npm install --save-dev jetifier
```
Then add it to the `postinstall` script in `package.json`:
```json
"scripts": {
"postinstall": "jetifier -r"
}
```
> Note: Remember to remove this when you upgrade to React Native 0.60 and higher.
Now, run the `postinstall` script manually:
```bash
npm run postinstall
```
To finalize installation of `react-native-gesture-handler` for Android, make the following modifications to `MainActivity.java`:
```diff
package com.reactnavigation.example;
import com.facebook.react.ReactActivity;
+ import com.facebook.react.ReactActivityDelegate;
+ import com.facebook.react.ReactRootView;
+ import com.swmansion.gesturehandler.react.RNGestureHandlerEnabledRootView;
public class MainActivity extends ReactActivity {
@Override
protected String getMainComponentName() {
return "Example";
}
+ @Override
+ protected ReactActivityDelegate createReactActivityDelegate() {
+ return new ReactActivityDelegate(this, getMainComponentName()) {
+ @Override
+ protected ReactRootView createRootView() {
+ return new RNGestureHandlerEnabledRootView(MainActivity.this);
+ }
+ };
+ }
}
```
Then add the following at the top of your entry file, such as `index.js` or `App.js`:
```js
import 'react-native-gesture-handler';
```
> Note: When you use a navigator (such as stack navigator), you'll need to follow the installation instructions of that navigator for any additional dependencies. If you're getting an error "Unable to resolve module", you need to install that module in your project.
Now you are ready to build and run your app on the device/simulator.
Continue to ["Hello React Navigation"](hello-react-navigation.md) to start writing some code.
---
## Hello React Navigation
Source: https://reactnavigation.org/docs/4.x/hello-react-navigation
In a web browser, you can link to different pages using an anchor (``) tag. When the user clicks on a link, the URL is pushed to the browser history stack. When the user presses the back button, the browser pops the item from the top of the history stack, so the active page is now the previously visited page. React Native doesn't have a built-in idea of a global history stack like a web browser does -- this is where React Navigation enters the story.
React Navigation's stack navigator provides a way for your app to transition between screens and manage navigation history. If your app uses only one stack navigator then it is conceptually similar to how a web browser handles navigation state - your app pushes and pops items from the navigation stack as users interact with it, and this results in the user seeing different screens. A key difference between how this works in a web browser and in React Navigation is that React Navigation's stack navigator provides the gestures and animations that you would expect on Android and iOS when navigating between routes in the stack.
Lets start by demonstrating the most common navigator, `createStackNavigator`.
Before continuing, first install [`react-navigation-stack`](https://github.com/react-navigation/react-navigation/tree/4.x/packages/stack):
```bash npm2yarn
npm install react-navigation-stack @react-native-community/masked-view react-native-safe-area-context
```
## Creating a stack navigator
`createStackNavigator` is a function that returns a React component. It takes _a route configuration object_ and, optionally, _an options object_ (we omit this below, for now). `createAppContainer` is a function that returns a React component to take as a parameter the React component created by the `createStackNavigator`, and can be directly exported from `App.js` to be used as our App's root component.
Hello World
```js
import React from 'react';
import { View, Text } from 'react-native';
import { createAppContainer } from 'react-navigation';
import { createStackNavigator } from 'react-navigation-stack';
class HomeScreen extends React.Component {
render() {
return (
Home Screen
);
}
}
const AppNavigator = createStackNavigator({
Home: {
screen: HomeScreen,
},
});
export default createAppContainer(AppNavigator);
```
If you run this code, you will see a screen with an empty navigation bar and a grey content area containing your `HomeScreen` component. The styles you see for the navigation bar and the content area are the default configuration for a stack navigator, we'll learn how to configure those later.
> The casing of the route name doesn't matter -- you can use lowercase `home` or capitalized `Home`, it's up to you. We prefer capitalizing our route names.
> The only required configuration for a route is the `screen` component. You can read more about the other options available in the [StackNavigator reference](stack-navigator.md).
In React Native, the component exported from `App.js` is the entry point (or root component) for your app -- it is the component from which every other component descends. It's often useful to have more control over the component at the root of your app than you would get from exporting the result of `createAppContainer`, so let's export a component that just renders our `AppNavigator` stack navigator.
```js
const AppContainer = createAppContainer(AppNavigator);
export default class App extends React.Component {
render() {
return ;
}
}
```
## Route configuration shorthand
Given that the only route configuration we have for `Home` is the screen component, we don't need to use the `{ screen: HomeScreen }` configuration format, we can use the screen component directly.
```js
const AppNavigator = createStackNavigator({
Home: HomeScreen,
});
```
## Adding a second route
The `` component doesn't accept any props -- all configuration is specified in the `options` parameter to the `AppNavigator` `createStackNavigator` function. We left the `options` blank, so it just uses the default configuration. To see an example of using the `options` object, we will add a second screen to the stack navigator.
```js
// Other code for HomeScreen here...
class DetailsScreen extends React.Component {
render() {
return (
Details Screen
);
}
}
const AppNavigator = createStackNavigator(
{
Home: HomeScreen,
Details: DetailsScreen,
},
{
initialRouteName: 'Home',
}
);
// Other code for App component here...
```
Now our stack has two _routes_, a `Home` route and a `Details` route. The `Home` route corresponds to the `HomeScreen` component, and the `Details` route corresponds to the `DetailsScreen` component. The initial route for the stack is the `Home` route. The natural question at this point is: "how do I go from the Home route to the Details route?". That is covered in the next section.
## Summary
- React Native doesn't have a built-in API for navigation like a web browser does. React Navigation provides this for you, along with the iOS and Android gestures and animations to transition between screens.
- `createStackNavigator` is a function that takes a route configuration object and an options object and returns a React component.
- The keys in the route configuration object are the route names and the values are the configuration for that route. The only required property on the configuration is the `screen` (the component to use for the route).
- To specify what the initial route in a stack is, provide an `initialRouteName` on the stack options object.
---
## Moving between screens
Source: https://reactnavigation.org/docs/4.x/navigating
In the previous section, ["Hello React Navigation"](hello-react-navigation.md), we defined a stack navigator with two routes (`Home` and `Details`), but we didn't learn how to let a user navigate from `Home` to `Details` (although we did learn how to change the _initial_ route in our code, but forcing our users to clone our repository and change the route in our code in order to see another screen is arguably among the worst user experiences one could imagine).
If this was a web browser, we'd be able to write something like this:
```
Go to Details
```
Another way to write this would be:
```
{ document.location.href = "details.html"; }}>Go to Details
```
We'll do something similar to the latter, but rather than using a `document` global we'll use the `navigation` prop that is passed down to our screen components.
## Navigating to a new screen
First navigation
```js
import * as React from 'react';
import { Button, View, Text } from 'react-native';
import { createAppContainer } from 'react-navigation';
import { createStackNavigator } from 'react-navigation-stack';
class HomeScreen extends React.Component {
render() {
return (
Home Screen
);
}
}
// ... other code from the previous section
```
Let's break this down:
- `this.props.navigation`: the `navigation` prop is passed in to every **screen component** ([definition](glossary-of-terms.md#screen-component)) in stack navigator (more about this later in ["The navigation prop in depth"](navigation-prop.md)).
- `navigate('Details')`: we call the `navigate` function (on the `navigation` prop — naming is hard!) with the name of the route that we'd like to move the user to.
> If we call `this.props.navigation.navigate` with a route name that we haven't defined on a stack navigator, nothing will happen. Said another way, we can only navigate to routes that have been defined on our stack navigator — we cannot navigate to an arbitrary component.
So we now have a stack with two routes: 1) the Home route 2) the Details route. What would happen if we navigated to the Details route again, from the Details screen?
## Navigate to a route multiple times
```js
class DetailsScreen extends React.Component {
render() {
return (
Details Screen
);
}
}
```
If you run this code, you'll notice that when you tap "Go to Details... again" that it doesn't do anything! This is because we are already on the Details route. The `navigate` function roughly means "go to this screen", and if you are already on that screen then it makes sense that it would do nothing.
Let's suppose that we actually _want_ to add another details screen. This is pretty common in cases where you pass in some unique data to each route (more on that later when we talk about `params`!). To do this, we can change `navigate` to `push`. This allows us to express the intent to add another route regardless of the existing navigation history.
push
```js