You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Copy file name to clipboardExpand all lines: versioned_docs/version-7.x/custom-navigators.md
+51-11Lines changed: 51 additions & 11 deletions
Original file line number
Diff line number
Diff line change
@@ -4,26 +4,60 @@ title: Custom navigators
4
4
sidebar_label: Custom navigators
5
5
---
6
6
7
-
Navigators allow you to define your application's navigation structure. Navigators also render common elements such as headers and tab bars which you can configure.
7
+
In essence, a navigator is a React component that takes a set of screens and options, and renders them based on its [navigation state](navigation-state.md), generally with additional UI such as headers, tab bars, or drawers.
8
8
9
-
Under the hood, navigators are plain React components.
9
+
React Navigation provides a few built-in navigators, but they might not always fit your needs if you want a very custom behavior or UI. In such cases, you can build your own custom navigators using React Navigation's APIs.
10
10
11
-
## Built-in Navigators
11
+
A custom navigator behaves just like a built-in navigator, and can be used in the same way. This means you can define screens the same way, use [route](route-object.md) and [navigation](navigation-prop.md) objects in your screens, and navigate between screens with familiar API. The navigator will also be able to handle deep linking, state persistence, and other features that built-in navigators support.
12
12
13
-
We include some commonly needed navigators such as:
13
+
## Overview
14
14
15
-
-[`createStackNavigator`](stack-navigator.md) - Renders one screen at a time and provides transitions between screens. When a new screen is opened it is placed on top of the stack.
16
-
-[`createDrawerNavigator`](drawer-navigator.md) - Provides a drawer that slides in from the left of the screen by default.
17
-
-[`createBottomTabNavigator`](bottom-tab-navigator.md) - Renders a tab bar that lets the user switch between several screens.
18
-
-[`createMaterialTopTabNavigator`](material-top-tab-navigator.md) - Renders tab view which lets the user switch between several screens using swipe gesture or the tab bar.
15
+
Under the hood, navigators are plain React components that use the [`useNavigationBuilder`](#usenavigationbuilder) hook.
19
16
20
-
## API for building custom navigators
17
+
The navigator component then uses this state to layout the screens appropriately with any additional UI based on the use case. This component is then wrapped in [`createNavigatorFactory`](#createnavigatorfactory) to create the API for the navigator.
21
18
22
-
A navigator bundles a router and a view which takes the [navigation state](navigation-state.md) and decides how to render it. We export a `useNavigationBuilder` hook to build custom navigators that integrate with rest of React Navigation.
Now, we have an already working navigator, even though it doesn't do anything special yet.
38
+
39
+
Let's break this down:
40
+
41
+
- We define a `MyNavigator` component that contains our navigator logic. This is the component that's rendered when you render `<Stack.Navigator>` in your app with the `createMyStackNavigator` factory function.
42
+
- We use the `useNavigationBuilder` hook and pass it [`StackRouter`](custom-routers.md#built-in-routers), which would make our navigator behave like a stack navigator. Any other router such as `TabRouter`, `DrawerRouter`, or a custom router can be used here as well.
43
+
- The hook returns the [navigation state](navigation-state.md) in the `state` property. This is the current state of the navigator. There's also a `descriptors` object which contains the data and helpers for each screen in the navigator.
44
+
- We get the focused route from the state with `state.routes[state.index]` - as `state.index` is the index of the currently focused route in the `state.routes` array.
45
+
- Then we get the corresponding descriptor for the focused route with `descriptors[focusedRoute.key]` and call the `render()` method on it to get the React element for the screen.
46
+
- The content of the navigator is wrapped in `NavigationContent` to provide appropriate context and wrappers.
47
+
48
+
With this, we have a basic stack navigator that renders only the focused screen. Unlike the built-in stack navigator, this doesn't keep unfocused screens rendered. But you can loop through `state.routes` and render all of the screens if you want to keep them mounted. You can also read `descriptor.options` to get the [options](screen-options.md) to handle the screen's title, header, and other options.
49
+
50
+
This also doesn't have any additional UI apart from the screen content. There are no gestures or animations. So you're free to add any additional UI, gestures, animations etc. as needed. You can also layout the screens in any way you want, such as rendering them side-by-side or in a grid, instead of stacking them on top of each other like the built-in stack navigator does.
51
+
52
+
You can see a more complete example of a custom navigator later in this document.
53
+
54
+
## API Definition
23
55
24
56
### `useNavigationBuilder`
25
57
26
-
This hook allows a component to hook into React Navigation. It accepts the following arguments:
58
+
This hook contains the core logic of a navigator, and is responsible for storing and managing the [navigation state](navigation-state.md). It takes a [router](custom-routers.md) as an argument to know how to handle various navigation actions. It then returns the state and helper methods for the navigator component to use.
59
+
60
+
It accepts the following arguments:
27
61
28
62
-`createRouter` - A factory method which returns a router object (e.g. `StackRouter`, `TabRouter`).
29
63
-`options` - Options for the hook and the router. The navigator should forward its props here so that user can provide props to configure the navigator. By default, the following options are accepted:
@@ -140,6 +174,12 @@ export function createMyNavigator(config) {
140
174
}
141
175
```
142
176
177
+
:::note
178
+
179
+
We can also do `exportconstcreateMyNavigator=createNavigatorFactory(MyNavigator)` directly instead of wrapping in another function. However, the wrapper function is necessary to have proper [TypeScript support](#type-checking-navigators) for the navigator.
0 commit comments