Skip to content

Update visual examples and added code examples #1214

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 11 commits into from
Mar 7, 2024
Binary file added static/assets/behavior/prevent-closing.mp4
Binary file not shown.
Binary file modified static/assets/headers/custom_headers.png
100755 → 100644
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added static/assets/headers/header-back-custom.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added static/assets/headers/header-button.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added static/assets/headers/header-custom-title.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added static/assets/headers/header-title.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added static/assets/headers/header-update-screen.mov
Binary file not shown.
Binary file added static/assets/modal/modal.mp4
Binary file not shown.
Binary file not shown.
Binary file removed static/assets/navigators/drawer/drawer.mov
Binary file not shown.
Binary file added static/assets/navigators/drawer/drawer.mp4
Binary file not shown.
Binary file added static/assets/navigators/lifecycle-focus.mov
Binary file not shown.
Binary file added static/assets/navigators/lifecycle.mov
Binary file not shown.
Binary file added static/assets/navigators/params-to-parent.mov
Binary file not shown.
Binary file added static/assets/navigators/passing-params.mov
Binary file not shown.
Binary file added static/assets/navigators/stack/back-home.mov
Binary file not shown.
Binary file modified static/assets/navigators/stack/basic_stack_nav.png
100755 → 100644
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added static/assets/navigators/stack/pop-to-top.mov
Binary file not shown.
Binary file added static/assets/navigators/stack/simple-details.mov
Binary file not shown.
Binary file modified static/assets/navigators/stack/stack-push.mov
100755 → 100644
Binary file not shown.
Binary file modified static/assets/navigators/tabs/tabs-badges.png
100755 → 100644
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added static/assets/navigators/tabs/tabs-minimal.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added static/assets/navigators/tabs/tabs-navigate.mp4
Binary file not shown.
Binary file not shown.
Binary file added static/assets/statusbar/status-drawer-android.mp4
Binary file not shown.
Binary file added static/assets/statusbar/status-drawer-ios.mp4
Binary file not shown.
Binary file added static/assets/statusbar/status-stack-android.mp4
Binary file not shown.
Binary file added static/assets/statusbar/status-stack-ios.mp4
Binary file not shown.
Binary file added static/assets/statusbar/status-tab-android.mp4
Binary file not shown.
Binary file added static/assets/statusbar/status-tab-ios.mp4
Binary file not shown.
12 changes: 6 additions & 6 deletions versioned_docs/version-6.x/drawer-based-navigation.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,12 +6,6 @@ sidebar_label: Drawer navigation

Common pattern in navigation is to use drawer from left (sometimes right) side for navigating between screens.

<div style={{ display: 'flex', margin: '16px 0' }}>
<video playsInline autoPlay muted loop>
<source src="/assets/navigators/drawer/drawer.mov" />
</video>
</div>

Before continuing, first install and configure [`@react-navigation/drawer`](https://github.com/react-navigation/react-navigation/tree/main/packages/drawer) and its dependencies following the [installation instructions](drawer-navigator.md#installation).

## Minimal example of drawer-based navigation
Expand Down Expand Up @@ -60,6 +54,12 @@ export default function App() {
}
```

<div style={{ display: 'flex', margin: '16px 0' }}>
<video playsInline autoPlay muted loop style={{ maxWidth: '280px' }}>
<source src="/assets/navigators/drawer/drawer.mp4" />
</video>
</div>

## Opening and closing drawer

To open and close drawer, use the following helpers:
Expand Down
28 changes: 28 additions & 0 deletions versioned_docs/version-6.x/header-buttons.md
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,8 @@ function StackScreen() {
}
```

![Header button](/assets/headers/header-button.png)

When we define our button this way, the `this` variable in `options` is _not_ the `HomeScreen` instance, so you can't call `setState` or any instance methods on it. This is pretty important because it's extremely common to want the buttons in your header to interact with the screen that the header belongs to. So, we will look how to do this next.

> 💡 Please note that a community-developed library for rendering buttons in the header with the correct styling is available: [react-navigation-header-buttons](https://github.com/vonovak/react-navigation-header-buttons).
Expand Down Expand Up @@ -81,6 +83,12 @@ function HomeScreen({ navigation }) {
}
```

<div style={{ display: 'flex', margin: '16px 0' }}>
<video playsInline autoPlay muted loop style={{ maxWidth: '280px' }}>
<source src="/assets/headers/header-update-screen.mov" />
</video>
</div>

Here we update the `headerRight` with a button with `onPress` handler that has access to the component's state and can update it.

## Customizing the back button
Expand All @@ -91,6 +99,26 @@ You can change the label behavior with `headerBackTitle` and style it with `head

To customize the back button image, you can use `headerBackImageSource` ([read more](native-stack-navigator.md#headerbackimagesource)).

```js
<Stack.Navigator>
<Stack.Screen
name="Home"
component={HomeScreen}
/>
<Stack.Screen
name="Details"
component={DetailsScreen}
options={
{
headerBackTitle: 'Custom Back',
headerBackTitleStyle: {fontSize: 30}
}}
/>
</Stack.Navigator>
```

![Header custom back](/assets/headers/header-back-custom.png)

## Overriding the back button

The back button will be rendered automatically in a stack navigator whenever it is possible for the user to go back from their current screen &mdash; in other words, the back button will be rendered whenever there is more than one screen in the stack.
Expand Down
4 changes: 4 additions & 0 deletions versioned_docs/version-6.x/headers.md
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,8 @@ function StackScreen() {
}
```

![Header title](/assets/headers/header-title.png)

## Using params in the title

In order to use params in the title, we need to make `options` prop for the screen a function that returns a configuration object. It might be tempting to try to use `this.props` inside of `options`, but because it is defined before the component is rendered, `this` does not refer to an instance of the component and therefore no props are available. Instead, if we make `options` a function then React Navigation will call it with an object containing `{ navigation, route }` - in this case, all we care about is `route`, which is the same object that is passed to your screen props as `route` prop. You may recall that we can get the params through `route.params`, and so we do this below to extract a param and use it as a title.
Expand Down Expand Up @@ -173,6 +175,8 @@ function StackScreen() {
}
```

![Header custom title](/assets/headers/header-custom-title.png)

:::note

You might be wondering, why `headerTitle` when we provide a component and not `title`, like before? The reason is that `headerTitle` is a property that is specific to headers, whereas `title` will be used for tab bars, drawers etc. as well. The `headerTitle` defaults to a `Text` component that displays the `title`.
Expand Down
8 changes: 6 additions & 2 deletions versioned_docs/version-6.x/modal.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,6 @@ title: Opening a modal
sidebar_label: Opening a modal
---

![Modal shown on screen](/assets/modal/modal-demo.gif)

A modal displays content that temporarily blocks interactions with the main view.

A modal is like a popup &mdash; it usually has a different transition animation, and is intended to focus on one particular interaction or piece of content.
Expand Down Expand Up @@ -61,6 +59,12 @@ function RootStackScreen() {
}
```

<div style={{ display: 'flex', margin: '16px 0' }}>
<video playsInline autoPlay muted loop style={{ maxWidth: '280px' }}>
<source src="/assets/modal/modal.mp4" />
</video>
</div>

Here, we are creating 2 groups of screens using the `RootStack.Group` component. The first group is for our regular screens, and the second group is for our modal screens. For the modal group, we have specified `presentation: 'modal'` in `screenOptions`. This will apply this option to all the screens inside the group. This option will change the animation for the screens to animate from bottom-to-top rather than right to left. The `presentation` option for stack navigator can be either `card` (default) or `modal`. The `modal` behavior slides the screen in from the bottom and allows the user to swipe down from the top to dismiss it on iOS.

Instead of specifying this option for a group, it's also possible to specify it for a single screen using the `options` prop on `RootStack.Screen`.
Expand Down
6 changes: 6 additions & 0 deletions versioned_docs/version-6.x/multiple-drawers.md
Original file line number Diff line number Diff line change
Expand Up @@ -190,6 +190,12 @@ export default function App() {
}
```

<div style={{ display: 'flex', margin: '16px 0' }}>
<video playsInline autoPlay muted loop style={{ maxWidth: '280px' }}>
<source src="/assets/navigators/drawer/drawer-multiple.mp4" />
</video>
</div>

But there is one problem. When we call `navigation.openDrawer()` in our `HomeScreen`, it always opens the left drawer since it's the immediate parent of the screen.

To solve this, we need to use [`navigation.getParent`](navigation-prop.md#getparent) to refer to the right drawer which is the parent of the left drawer. So our code would look like:
Expand Down
20 changes: 19 additions & 1 deletion versioned_docs/version-6.x/navigating.md
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,12 @@ function HomeScreen({ navigation }) {
// ... other code from the previous section
```

<div style={{ display: 'flex', margin: '16px 0' }}>
<video playsInline autoPlay muted loop style={{ maxWidth: '280px' }}>
<source src="/assets/navigators/stack/simple-details.mov" />
</video>
</div>

Let's break this down:

- `navigation` - the `navigation` prop is passed in to every **screen component** ([definition](glossary-of-terms.md#screen-component)) in the native stack navigator (more about this later in ["The navigation prop in depth"](navigation-prop.md)).
Expand Down Expand Up @@ -96,7 +102,7 @@ Let's suppose that we actually _want_ to add another details screen. This is pre
```

<div style={{ display: 'flex', margin: '16px 0' }}>
<video playsInline autoPlay muted loop>
<video playsInline autoPlay muted loop style={{ maxWidth: '280px' }}>
<source src="/assets/navigators/stack/stack-push.mov" />
</video>
</div>
Expand Down Expand Up @@ -127,6 +133,12 @@ function DetailsScreen({ navigation }) {
}
```

<div style={{ display: 'flex', margin: '16px 0' }}>
<video playsInline autoPlay muted loop style={{ maxWidth: '280px' }}>
<source src="/assets/navigators/stack/back-home.mov" />
</video>
</div>

:::note

On Android, React Navigation hooks in to the hardware back button and fires the `goBack()` function for you when the user presses it, so it behaves as the user would expect.
Expand Down Expand Up @@ -157,6 +169,12 @@ function DetailsScreen({ navigation }) {
}
```

<div style={{ display: 'flex', margin: '16px 0' }}>
<video playsInline autoPlay muted loop style={{ maxWidth: '280px' }}>
<source src="/assets/navigators/stack/pop-to-top.mov" />
</video>
</div>

## Summary

- `navigation.navigate('RouteName')` pushes a new route to the native stack navigator if it's not already in the stack, otherwise it jumps to that screen.
Expand Down
12 changes: 12 additions & 0 deletions versioned_docs/version-6.x/navigation-lifecycle.md
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,12 @@ function App() {
}
```

<div style={{ display: 'flex', margin: '16px 0' }}>
<video playsInline autoPlay muted loop style={{ maxWidth: '280px' }}>
<source src="/assets/navigators/lifecycle.mov" />
</video>
</div>

We start on the `HomeScreen` and navigate to `DetailsScreen`. Then we use the tab bar to switch to the `SettingsScreen` and navigate to `ProfileScreen`. After this sequence of operations is done, all 4 of the screens are mounted! If you use the tab bar to switch back to the `HomeStack`, you'll notice you'll be presented with the `DetailsScreen` - the navigation state of the `HomeStack` has been preserved!

## React Navigation lifecycle events
Expand Down Expand Up @@ -104,6 +110,12 @@ function Profile() {
}
```

<div style={{ display: 'flex', margin: '16px 0' }}>
<video playsInline autoPlay muted loop style={{ maxWidth: '280px' }}>
<source src="/assets/navigators/lifecycle-focus.mov" />
</video>
</div>

If you want to render different things based on if the screen is focused or not, you can use the [`useIsFocused`](use-is-focused.md) hook which returns a boolean indicating whether the screen is focused.

## Summary
Expand Down
12 changes: 11 additions & 1 deletion versioned_docs/version-6.x/params.md
Original file line number Diff line number Diff line change
Expand Up @@ -64,7 +64,11 @@ function DetailsScreen({ route, navigation }) {
}
```

![Screen with passed parameters](/assets/navigators/passing_params.png)
<div style={{ display: 'flex', margin: '16px 0' }}>
<video playsInline autoPlay muted loop style={{ maxWidth: '280px' }}>
<source src="/assets/navigators/passing-params.mov" />
</video>
</div>

## Initial params

Expand Down Expand Up @@ -156,6 +160,12 @@ function CreatePostScreen({ navigation, route }) {
}
```

<div style={{ display: 'flex', margin: '16px 0' }}>
<video playsInline autoPlay muted loop style={{ maxWidth: '280px' }}>
<source src="/assets/navigators/params-to-parent.mov" />
</video>
</div>

Here, after you press "Done", the home screen's `route.params` will be updated to reflect the post text that you passed in `navigate`.

## Passing params to nested navigators
Expand Down
6 changes: 6 additions & 0 deletions versioned_docs/version-6.x/preventing-going-back.md
Original file line number Diff line number Diff line change
Expand Up @@ -57,6 +57,12 @@ function EditText({ navigation }) {
}
```

<div style={{ display: 'flex', margin: '16px 0' }}>
<video playsInline autoPlay muted loop style={{ maxWidth: '280px' }}>
<source src="/assets/behavior/prevent-closing.mp4" />
</video>
</div>

Previously, the way to do this was to:

- Override back button in header
Expand Down
29 changes: 25 additions & 4 deletions versioned_docs/version-6.x/status-bar.md
Original file line number Diff line number Diff line change
Expand Up @@ -99,7 +99,14 @@ const styles = StyleSheet.create({
});
```

![StackNavigator with different StatusBar configs](/assets/statusbar/statusbar-stack-demo.gif)
<div style={{ display: 'flex', margin: '16px 0' }}>
<video playsInline autoPlay muted loop style={{ maxWidth: '280px' }}>
<source src="/assets/statusbar/status-stack-ios.mp4" />
</video>
<video playsInline autoPlay muted loop style={{ maxWidth: '280px' }}>
<source src="/assets/statusbar/status-stack-android.mp4" />
</video>
</div>

## Tabs and Drawer

Expand Down Expand Up @@ -180,6 +187,20 @@ function Screen2({ navigation }) {

Although not necessary, you can use the `FocusAwareStatusBar` component in the screens of the native stack navigator as well.

![DrawerNavigator with different StatusBar configs](/assets/statusbar/statusbar-drawer-demo.gif)

![TabNavigator with different StatusBar configs](/assets/statusbar/statusbar-tab-demo.gif)
<div style={{ display: 'flex', margin: '16px 0' }}>
<video playsInline autoPlay muted loop style={{ maxWidth: '280px' }}>
<source src="/assets/statusbar/status-drawer-ios.mp4" />
</video>
<video playsInline autoPlay muted loop style={{ maxWidth: '280px' }}>
<source src="/assets/statusbar/status-drawer-android.mp4" />
</video>
</div>

<div style={{ display: 'flex', margin: '16px 0' }}>
<video playsInline autoPlay muted loop style={{ maxWidth: '280px' }}>
<source src="/assets/statusbar/status-tab-ios.mp4" />
</video>
<video playsInline autoPlay muted loop style={{ maxWidth: '280px' }}>
<source src="/assets/statusbar/status-tab-android.mp4" />
</video>
</div>
14 changes: 14 additions & 0 deletions versioned_docs/version-6.x/tab-based-navigation.md
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,8 @@ export default function App() {
}
```

![Tabs minimal](/assets/navigators/tabs/tabs-minimal.png)

## Customizing the appearance

This is similar to how you would customize a stack navigator &mdash; there are some properties that are set when you initialize the tab navigator and others that can be customized per-screen in `options`.
Expand Down Expand Up @@ -147,6 +149,12 @@ function SettingsScreen({ navigation }) {
}
```

<div style={{ display: 'flex', margin: '16px 0' }}>
<video playsInline autoPlay muted loop style={{ maxWidth: '280px' }}>
<source src="/assets/navigators/tabs/tabs-navigate.mp4" />
</video>
</div>

## A stack navigator for each tab

Usually tabs don't just display one screen &mdash; for example, on your Twitter feed, you can tap on a tweet and it brings you to a new screen within that tab with all of the replies. You can think of this as there being separate navigation stacks within each tab, and that's exactly how we will model it in React Navigation.
Expand Down Expand Up @@ -228,6 +236,12 @@ export default function App() {
}
```

<div style={{ display: 'flex', margin: '16px 0' }}>
<video playsInline autoPlay muted loop style={{ maxWidth: '280px' }}>
<source src="/assets/navigators/tabs/tabs-with-stack.mp4" />
</video>
</div>

## Why do we need a TabNavigator instead of TabBarIOS or some other component?

It's common to attempt to use a standalone tab bar component without integrating it into the navigation library you use in your app. In some cases, this works fine! You should be warned, however, that you may run into some frustrating unanticipated issues when doing this.
Expand Down
17 changes: 10 additions & 7 deletions versioned_docs/version-7.x/drawer-based-navigation.md
Original file line number Diff line number Diff line change
Expand Up @@ -9,12 +9,6 @@ import TabItem from '@theme/TabItem';

Common pattern in navigation is to use drawer from left (sometimes right) side for navigating between screens.

<div style={{ display: 'flex', margin: '16px 0' }}>
<video playsInline autoPlay muted loop>
<source src="/assets/navigators/drawer/drawer.mov" />
</video>
</div>

Before continuing, first install and configure [`@react-navigation/drawer`](https://github.com/react-navigation/react-navigation/tree/main/packages/drawer) and its dependencies following the [installation instructions](drawer-navigator.md#installation).

## Minimal example of drawer-based navigation
Expand Down Expand Up @@ -117,6 +111,11 @@ export default function App() {
}
```

<div style={{ display: 'flex', margin: '16px 0' }}>
<video playsInline autoPlay muted loop style={{ maxWidth: '280px' }}>
<source src="/assets/navigators/drawer/drawer.mp4" />
</video>
</div>
</TabItem>
</Tabs>

Expand Down Expand Up @@ -530,7 +529,11 @@ export default function App() {
```js name="Navigation dispatcher" snack version=7
import * as React from 'react';
import { View, Text, Button } from 'react-native';
import { NavigationContainer, useNavigation, DrawerActions } from '@react-navigation/native';
import {
NavigationContainer,
useNavigation,
DrawerActions,
} from '@react-navigation/native';
import {
createDrawerNavigator,
DrawerContentScrollView,
Expand Down
24 changes: 24 additions & 0 deletions versioned_docs/version-7.x/header-buttons.md
Original file line number Diff line number Diff line change
Expand Up @@ -102,6 +102,9 @@ export default function App() {
}
```

![Header button](/assets/headers/header-button.png)

When we define our button this way, the `this` variable in `options` is _not_ the `HomeScreen` instance, so you can't call `setState` or any instance methods on it. This is pretty important because it's extremely common to want the buttons in your header to interact with the screen that the header belongs to. So, we will look how to do this next.
</TabItem>
</Tabs>

Expand Down Expand Up @@ -170,6 +173,11 @@ export default function App() {
}
```

<div style={{ display: 'flex', margin: '16px 0' }}>
<video playsInline autoPlay muted loop style={{ maxWidth: '280px' }}>
<source src="/assets/headers/header-update-screen.mov" />
</video>
</div>
</TabItem>
<TabItem value="dynamic" label="Dynamic">

Expand Down Expand Up @@ -240,6 +248,22 @@ You can change the label behavior with `headerBackTitle` and style it with `head

To customize the back button image, you can use `headerBackImageSource` ([read more](native-stack-navigator.md#headerbackimagesource)).

```js
<Stack.Navigator>
<Stack.Screen name="Home" component={HomeScreen} />
<Stack.Screen
name="Details"
component={DetailsScreen}
options={{
headerBackTitle: 'Custom Back',
headerBackTitleStyle: { fontSize: 30 },
}}
/>
</Stack.Navigator>
```

![Header custom back](/assets/headers/header-back-custom.png)

## Overriding the back button

The back button will be rendered automatically in a stack navigator whenever it is possible for the user to go back from their current screen &mdash; in other words, the back button will be rendered whenever there is more than one screen in the stack.
Expand Down
Loading