Skip to content

Commit 8e935f2

Browse files
committed
Update custom navigator docs
1 parent 73e30ad commit 8e935f2

2 files changed

Lines changed: 88 additions & 31 deletions

File tree

versioned_docs/version-7.x/custom-navigators.md

Lines changed: 18 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -7,11 +7,11 @@ sidebar_label: Custom navigators
77
import Tabs from '@theme/Tabs';
88
import TabItem from '@theme/TabItem';
99

10-
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.
10+
In essence, a navigator is a React component that takes a set of [screens](screen.md) and options, and renders them based on its [navigation state](navigation-state.md), generally with additional UI such as [headers](headers.md), [tab bars](bottom-tab-navigator.md), or [drawers](drawer-navigator.md).
1111

1212
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.
1313

14-
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-object.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.
14+
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-object.md) objects in your screens, and navigate between screens with familiar API. The navigator will also be able to handle [deep linking](deep-linking.md), [state persistence](state-persistence.md), and other features that built-in navigators support.
1515

1616
## Overview
1717

@@ -48,27 +48,27 @@ Now, we have an already working navigator, even though it doesn't do anything sp
4848
Let's break this down:
4949

5050
- We define a `MyNavigator` component that contains our navigator logic. This is the component that's rendered when you render the navigator in your app with the `createMyNavigator` factory function.
51-
- 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.
51+
- 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](custom-routers.md) can be used here as well.
5252
- 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.
5353
- 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.
5454
- 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.
5555
- The content of the navigator is wrapped in `NavigationContent` to provide appropriate context and wrappers.
5656

5757
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.
5858

59-
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.
59+
The navigator only renders what's written in the component and 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.
6060

6161
You can see a more complete example of a custom navigator later in this document.
6262

6363
## API Definition
6464

6565
### `useNavigationBuilder`
6666

67-
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.
67+
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](navigation-actions.md). It then returns the state and helper methods for the navigator component to use.
6868

6969
It accepts the following arguments:
7070

71-
- `createRouter` - A factory method which returns a router object (e.g. `StackRouter`, `TabRouter`).
71+
- `createRouter` - A factory method which returns a [router](custom-routers.md) object (e.g. `StackRouter`, `TabRouter`).
7272
- `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:
7373
- `children` (required) - The `children` prop should contain route configurations as `Screen` components.
7474
- `screenOptions` - The `screenOptions` prop should contain default options for all of the screens.
@@ -79,7 +79,7 @@ It accepts the following arguments:
7979
The hook returns an object with following properties:
8080

8181
- `state` - The [navigation state](navigation-state.md) for the navigator. The component can take this state and decide how to render it.
82-
- `navigation` - The navigation object containing various helper methods for the navigator to manipulate the [navigation state](navigation-state.md). This isn't the same as the navigation object for the screen and includes some helpers such as `emit` to emit events to the screens.
82+
- `navigation` - The [navigation object](navigation-object.md) containing various helper methods for the navigator to manipulate the [navigation state](navigation-state.md). This isn't the same as the navigation object for the screen and includes some helpers such as `emit` to emit [events](navigation-events.md) to the screens.
8383
- `descriptors` - This is an object containing descriptors for each route with the route keys as its properties. The descriptor for a route can be accessed by `descriptors[route.key]`. Each descriptor contains the following properties:
8484
- `navigation` - The navigation object for the screen. You don't need to pass this to the screen manually. But it's useful if we're rendering components outside the screen that need to receive `navigation` prop as well, such as a header component.
8585
- `options` - A getter which returns the options such as `title` for the screen if they are specified.
@@ -147,7 +147,7 @@ function TabNavigator({ tabBarStyle, contentStyle, ...rest }) {
147147
}
148148
```
149149
150-
The `navigation` object for navigators also has an `emit` method to emit custom events to the child screens. The usage looks like this:
150+
The `navigation` object for navigators also has an `emit` method to emit [custom events](navigation-events.md) to the child screens. The usage looks like this:
151151
152152
```js
153153
navigation.emit({
@@ -163,7 +163,9 @@ The `target` property determines the screen that will receive the event. If the
163163
164164
### `createNavigatorFactory`
165165
166-
This `createNavigatorFactory` function is used to create a function that will `Navigator` and `Screen` pair. Custom navigators need to wrap the navigator component in `createNavigatorFactory` before exporting.
166+
This `createNavigatorFactory` function is used to create a navigator factory function, which creates `Navigator` and `Screen` pair for the dynamic configuration or navigator objects for static configuration.
167+
168+
So custom navigators need to wrap the navigator component in `createNavigatorFactory` before exporting to make it useable.
167169
168170
Example:
169171
@@ -267,7 +269,8 @@ type MyNavigationEventMap = {
267269
};
268270

269271
// The type of the navigation object for each screen
270-
type MyNavigationProp<
272+
// Needed for manual annotation of the navigation objects
273+
export type MyNavigationProp<
271274
ParamList extends ParamListBase,
272275
RouteName extends keyof ParamList = keyof ParamList,
273276
NavigatorID extends string | undefined = undefined,
@@ -295,6 +298,7 @@ type Props = DefaultNavigatorOptions<
295298

296299
function TabNavigator({ tabBarStyle, contentStyle, ...rest }: Props) {
297300
const { state, navigation, descriptors, NavigationContent } =
301+
// Generic parameters containing state, options, actions, events etc. types.
298302
useNavigationBuilder<
299303
TabNavigationState<ParamListBase>,
300304
TabRouterOptions,
@@ -391,7 +395,7 @@ export function createMyNavigator<
391395
392396
## Extending Navigators
393397
394-
All of the built-in navigators export their views, which we can reuse and build additional functionality on top of them. For example, if we want to re-build the bottom tab navigator, we need the following code:
398+
All of the built-in navigators export their views, which we can reuse and build additional functionality on top of them. For example, if we want to re-build the [bottom tab navigator](bottom-tab-navigator.md), we need the following code:
395399
396400
```js
397401
import * as React from 'react';
@@ -402,7 +406,7 @@ import {
402406
} from '@react-navigation/native';
403407
import { BottomTabView } from '@react-navigation/bottom-tabs';
404408

405-
function BottomTabNavigator({
409+
function MyBottomTabNavigator({
406410
initialRouteName,
407411
children,
408412
layout,
@@ -436,11 +440,11 @@ function BottomTabNavigator({
436440
}
437441

438442
export function createMyNavigator(config) {
439-
return createNavigatorFactory(BottomTabNavigator)(config);
443+
return createNavigatorFactory(MyBottomTabNavigator)(config);
440444
}
441445
```
442446
443-
Now, we can customize it to add additional functionality or change the behavior. For example, use a [custom router](custom-routers.md) instead of the default `TabRouter`:
447+
Now, we can customize it to add additional functionality or change the behavior. For example, use a [custom router](custom-routers.md) instead of the default [`TabRouter`](custom-routers.md#built-in-routers):
444448
445449
```js
446450
import MyRouter from './MyRouter';

0 commit comments

Comments
 (0)