From 1e1f7f160f54747b41fc45a521ab4d9113269618 Mon Sep 17 00:00:00 2001 From: Satyajit Sahoo Date: Thu, 19 Mar 2026 17:07:59 +0100 Subject: [PATCH 1/2] Various improvements --- versioned_docs/version-8.x/auth-flow.md | 40 ++++++----- .../version-8.x/bottom-tab-navigator.md | 16 +++-- .../combine-static-with-dynamic.md | 6 +- .../version-8.x/community-navigators.md | 2 +- .../version-8.x/configuring-links.md | 36 +++++----- versioned_docs/version-8.x/contributing.md | 6 +- .../custom-android-back-button-handling.md | 8 +-- versioned_docs/version-8.x/custom-routers.md | 66 +++++++++---------- .../version-8.x/customizing-bottom-tabs.md | 12 +++- versioned_docs/version-8.x/deep-linking.md | 14 ++-- versioned_docs/version-8.x/drawer-actions.md | 1 + versioned_docs/version-8.x/drawer-layout.md | 14 ++-- .../version-8.x/drawer-navigator.md | 7 +- versioned_docs/version-8.x/elements.md | 44 +++++++------ versioned_docs/version-8.x/group.md | 2 +- .../version-8.x/handling-safe-area.md | 4 +- versioned_docs/version-8.x/headers.md | 17 +++-- .../version-8.x/hello-react-navigation.md | 2 +- .../version-8.x/material-top-tab-navigator.md | 4 +- versioned_docs/version-8.x/modal.md | 4 +- versioned_docs/version-8.x/more-resources.md | 2 + .../version-8.x/multiple-drawers.md | 8 ++- .../version-8.x/native-stack-navigator.md | 6 +- .../navigating-without-navigation-prop.md | 8 +-- .../version-8.x/navigation-actions.md | 12 ++-- .../version-8.x/navigation-container.md | 14 +++- .../version-8.x/navigation-events.md | 6 +- .../version-8.x/navigation-lifecycle.md | 2 +- .../version-8.x/navigation-object.md | 33 +++++----- .../version-8.x/nesting-navigators.md | 16 +++-- versioned_docs/version-8.x/params.md | 12 ++-- versioned_docs/version-8.x/route-object.md | 21 ++++-- .../version-8.x/screen-options-resolution.md | 2 +- versioned_docs/version-8.x/screen-options.md | 18 +++-- versioned_docs/version-8.x/screen-tracking.md | 12 +--- .../version-8.x/server-container.md | 8 +-- .../version-8.x/server-rendering.md | 13 ++-- versioned_docs/version-8.x/stack-actions.md | 2 +- versioned_docs/version-8.x/stack-navigator.md | 5 +- .../version-8.x/static-configuration.md | 2 +- .../version-8.x/static-vs-dynamic.md | 7 +- versioned_docs/version-8.x/status-bar.md | 38 ++++------- versioned_docs/version-8.x/tab-view.md | 4 +- versioned_docs/version-8.x/testing.md | 29 ++++---- versioned_docs/version-8.x/themes.md | 2 + versioned_docs/version-8.x/troubleshooting.md | 10 +-- versioned_docs/version-8.x/typescript.md | 4 +- .../version-8.x/upgrading-from-7.x.md | 6 +- .../version-8.x/use-focus-effect.md | 4 +- .../version-8.x/use-link-builder.md | 6 +- versioned_docs/version-8.x/use-link-props.md | 2 +- versioned_docs/version-8.x/use-link-to.md | 14 +++- .../version-8.x/use-navigation-state.md | 2 +- versioned_docs/version-8.x/use-route-path.md | 1 + .../version-8.x/use-scroll-to-top.md | 6 +- versioned_docs/version-8.x/use-theme.md | 2 +- versioned_docs/version-8.x/web-support.md | 2 +- 57 files changed, 360 insertions(+), 286 deletions(-) diff --git a/versioned_docs/version-8.x/auth-flow.md b/versioned_docs/version-8.x/auth-flow.md index 2c5994d33e3..95ad90d6076 100755 --- a/versioned_docs/version-8.x/auth-flow.md +++ b/versioned_docs/version-8.x/auth-flow.md @@ -88,11 +88,11 @@ This means: This makes it impossible to navigate to the `Home` when the user is not signed in, and to `SignIn` when the user is signed in. -When the values returned by `useIsSignedin` and `useIsSignedOut` change, the screens matching the condition will change: +When the values returned by `useIsSignedIn` and `useIsSignedOut` change, the screens matching the condition will change: -- Let's say, initially `useIsSignedOut` returns `true`. This means that `SignIn` screens is shown. +- Let's say, initially `useIsSignedOut` returns `true`. This means that the `SignIn` screen is shown. - After the user signs in, the return value of `useIsSignedIn` will change to `true` and `useIsSignedOut` will change to `false`, which means: - - React Navigation will see that the `SignIn` screen is no longer matches the condition, so it will remove the screen. + - React Navigation will see that the `SignIn` screen no longer matches the condition, so it will remove the screen. - Then it'll show the `Home` screen automatically because that's the first screen available when `useIsSignedIn` returns `true`. The order of the screens matters when there are multiple screens matching the condition. For example, if there are two screens matching `useIsSignedIn`, the first screen will be shown when the condition is `true`. @@ -170,14 +170,14 @@ This means: This makes it impossible to navigate to the `Home` when the user is not signed in, and to `SignIn` when the user is signed in. -When the value of `isSignedin` changes, the screens defined based on the condition will change: +When the value of `isSignedIn` changes, the screens defined based on the condition will change: -- Let's say, initially `isSignedin` is `false`. This means that `SignIn` screens is shown. -- After the user signs in, the value of `isSignedin` will change to `true`, which means: +- Let's say, initially `isSignedIn` is `false`. This means that the `SignIn` screen is shown. +- After the user signs in, the value of `isSignedIn` will change to `true`, which means: - React Navigation will see that the `SignIn` screen is no longer defined, so it will remove the screen. - - Then it'll show the `Home` screen automatically because that's the first screen defined when `isSignedin` returns `true`. + - Then it'll show the `Home` screen automatically because that's the first screen defined when `isSignedIn` returns `true`. -The order of the screens matters when there are multiple screens matching the condition. For example, if there are two screens defined based on `isSignedin`, the first screen will be shown when the condition is `true`. +The order of the screens matters when there are multiple screens matching the condition. For example, if there are two screens defined based on `isSignedIn`, the first screen will be shown when the condition is `true`. @@ -228,16 +228,15 @@ export default function App() { {isSignedIn ? ( + + ) : ( - ) : ( - )} @@ -285,16 +284,15 @@ return ( {isSignedIn ? ( + + ) : ( - ) : ( - )} @@ -348,14 +346,14 @@ We can use [`React.Fragment`](https://react.dev/reference/react/Fragment) or [`G ```js isSignedIn ? ( <> - - - + + ) : ( <> - - + + + ); ``` diff --git a/versioned_docs/version-8.x/bottom-tab-navigator.md b/versioned_docs/version-8.x/bottom-tab-navigator.md index 5dd292240eb..146c779fab9 100755 --- a/versioned_docs/version-8.x/bottom-tab-navigator.md +++ b/versioned_docs/version-8.x/bottom-tab-navigator.md @@ -371,8 +371,11 @@ Example: ```js name="Search Tab on iOS 26" snack static2dynamic import * as React from 'react'; -import { View, Text, FlatList } from 'react-native'; -import { createStaticNavigation } from '@react-navigation/native'; +import { Platform, View, Text, FlatList } from 'react-native'; +import { + createStaticNavigation, + useNavigation, +} from '@react-navigation/native'; import { createBottomTabNavigator } from '@react-navigation/bottom-tabs'; import { createNativeStackNavigator } from '@react-navigation/native-stack'; @@ -903,7 +906,8 @@ const Tabs = createBottomTabNavigator({ ```js @@ -1326,7 +1330,7 @@ function MyComponent() { const tabBarHeight = useBottomTabBarHeight(); return ( - + {/* Content */} ); @@ -1563,8 +1567,6 @@ Bottom Tab Navigator exposes various options to configure the transition animati Putting these together, you can customize the transition animation for a screen: -Putting these together, you can customize the transition animation for a screen: - ```js name="Bottom Tabs custom animation" snack static2dynamic import * as React from 'react'; import { View, Text, Easing } from 'react-native'; @@ -1644,7 +1646,7 @@ import { TransitionSpecs } from '@react-navigation/bottom-tabs'; screen: Profile, options: { // highlight-start - transitionSpec: TransitionSpecs.CrossFadeSpec, + transitionSpec: TransitionSpecs.FadeSpec, // highlight-end }, }, diff --git a/versioned_docs/version-8.x/combine-static-with-dynamic.md b/versioned_docs/version-8.x/combine-static-with-dynamic.md index 1dc8dfac207..89f60783e97 100644 --- a/versioned_docs/version-8.x/combine-static-with-dynamic.md +++ b/versioned_docs/version-8.x/combine-static-with-dynamic.md @@ -39,7 +39,7 @@ const RootStack = createNativeStackNavigator({ }); ``` -Here, `FeedScreen` is a component that renders a tab navigator and is defined using the dynamic API: +Here, `FeedScreen` is a component that renders a bottom tab navigator and is defined using the dynamic API: ```js import { createBottomTabNavigator } from '@react-navigation/bottom-tabs'; @@ -58,8 +58,8 @@ function FeedScreen() { This code will work, but we're missing 2 things: -- Linking configuration for the screens in the top tab navigator. -- TypeScript types for the screens in the top tab navigator. +- Linking configuration for the screens in the bottom tab navigator. +- TypeScript types for the screens in the bottom tab navigator. Since the nested navigator is defined using the dynamic API, we need to handle these manually. For the linking configuration, we can define the screens in the `linking` property of the `Feed` screen: diff --git a/versioned_docs/version-8.x/community-navigators.md b/versioned_docs/version-8.x/community-navigators.md index f1d1d9feea9..31bb564e5b7 100755 --- a/versioned_docs/version-8.x/community-navigators.md +++ b/versioned_docs/version-8.x/community-navigators.md @@ -4,7 +4,7 @@ title: Community navigators sidebar_label: Community navigators --- -This guide lists various community navigators for React Navigation. These navigators offer provide UI components for navigation with the familiar React Navigation API. +This guide lists various community navigators for React Navigation. These navigators provide UI components for navigation with the familiar React Navigation API. If you're looking to build your own navigator, check out the [custom navigators guide](custom-navigators.md). diff --git a/versioned_docs/version-8.x/configuring-links.md b/versioned_docs/version-8.x/configuring-links.md index f412824a09f..2a5528744e4 100644 --- a/versioned_docs/version-8.x/configuring-links.md +++ b/versioned_docs/version-8.x/configuring-links.md @@ -485,7 +485,7 @@ const state = { sort: 'latest', }, }, - ]; + ], } ``` @@ -655,7 +655,9 @@ const RootStack = createStackNavigator({ date: (date) => { const d = new Date(date); - return d.getFullYear() + '-' + d.getMonth() + '-' + d.getDate(); + return ( + d.getFullYear() + '-' + (d.getMonth() + 1) + '-' + d.getDate() + ); }, }, }, @@ -687,7 +689,7 @@ const config = { date: (date) => { const d = new Date(date); - return d.getFullYear() + '-' + d.getMonth() + '-' + d.getDate(); + return d.getFullYear() + '-' + (d.getMonth() + 1) + '-' + d.getDate(); }, }, // highlight-end @@ -803,7 +805,7 @@ const HomeTabs = createBottomTabNavigator({ screen: FeedScreen, }, Profile: { - screen: HomeScreen, + screen: ProfileScreen, linking: { path: 'users/:id', }, @@ -902,7 +904,7 @@ const HomeTabs = createBottomTabNavigator({ screen: FeedScreen, }, Profile: { - screen: HomeScreen, + screen: ProfileScreen, linking: { path: 'users/:id', }, @@ -1015,7 +1017,7 @@ const HomeTabs = createBottomTabNavigator({ screen: FeedScreen, }, Profile: { - screen: HomeScreen, + screen: ProfileScreen, linking: { path: 'users/:id', }, @@ -1119,7 +1121,7 @@ By default, paths defined for each screen are matched against the URL relative t const ProfileTabs = createBottomTabNavigator({ screens: { Profile: { - screen: HomeScreen, + screen: ProfileScreen, linking: { path: 'users/:id', }, @@ -1171,7 +1173,7 @@ In this case, it makes more sense to navigate to the `Profile` screen using a UR const ProfileTabs = createBottomTabNavigator({ screens: { Profile: { - screen: HomeScreen, + screen: ProfileScreen, linking: { path: 'users/:id', // highlight-next-line @@ -1229,13 +1231,13 @@ Sometimes, you may not want to have the route name of a screen in the path. For const RootStack = createStackNavigator({ screens: { Home: { - screen: ProfileScreen, + screen: HomeScreen, linking: { path: 'home', }, }, Profile: { - screen: HomeScreen, + screen: ProfileScreen, linking: { path: 'users/:id', }, @@ -1272,13 +1274,13 @@ You can specify an empty string as path or not specify a path at all, and React const RootStack = createStackNavigator({ screens: { Home: { - screen: ProfileScreen, + screen: HomeScreen, linking: { path: '', }, }, Profile: { - screen: HomeScreen, + screen: ProfileScreen, linking: { path: 'users/:id', }, @@ -1386,7 +1388,7 @@ const config = { -You can also provide a your own function to serialize the params. For example, let's say that you want to use a DD-MM-YYYY format in the path instead of a timestamp: +You can also provide your own function to serialize the params. For example, let's say that you want to use a DD-MM-YYYY format in the path instead of a timestamp: @@ -1405,7 +1407,9 @@ const RootStack = createStackNavigator({ date: (date) => { const d = new Date(date); - return d.getFullYear() + '-' + d.getMonth() + '-' + d.getDate(); + return ( + d.getFullYear() + '-' + (d.getMonth() + 1) + '-' + d.getDate() + ); }, }, }, @@ -1429,7 +1433,7 @@ const config = { date: (date) => { const d = new Date(date); - return d.getFullYear() + '-' + d.getMonth() + '-' + d.getDate(); + return d.getFullYear() + '-' + (d.getMonth() + 1) + '-' + d.getDate(); }, }, }, @@ -1446,7 +1450,7 @@ Depending on your requirements, you can use this functionality to parse and stri If you need more complex matching logic, you can use regular expressions to match the path. For example, if you want to use the pattern `@username` to match a user's profile, you can use a regular expression to match the path. This allows you to have the same path pattern for multiple screens, but fine-tune the matching logic to be more specific for a particular screen. -Regular expressions can be specified between parentheses `(` and `)` in the after a param name. For example: +Regular expressions can be specified between parentheses `(` and `)` after a param name. For example: diff --git a/versioned_docs/version-8.x/contributing.md b/versioned_docs/version-8.x/contributing.md index ec05c128ca0..d7a104b873e 100755 --- a/versioned_docs/version-8.x/contributing.md +++ b/versioned_docs/version-8.x/contributing.md @@ -98,8 +98,8 @@ Much like the issue template, the [pull request template](https://github.com/rea - Run these commands in the terminal to download locally and install it: ```bash -git clone https://github.com//navigation-ex.git -cd navigation-ex +git clone https://github.com//react-navigation.git +cd react-navigation git remote add upstream https://github.com/react-navigation/react-navigation.git yarn ``` @@ -134,7 +134,7 @@ yarn typescript --watch ### Run the Example App -The [example app](https://github.com/react-navigation/react-navigation/tree/main/packages/example) includes a variety of patterns and is used as a simple way for contributors to manually integration test changes. +The [example app](https://github.com/react-navigation/react-navigation/tree/main/example) includes a variety of patterns and is used as a simple way for contributors to manually integration test changes. While developing, you can run the [example app](https://github.com/react-navigation/react-navigation/tree/main/example) with [Expo](https://expo.io/) to test your changes: diff --git a/versioned_docs/version-8.x/custom-android-back-button-handling.md b/versioned_docs/version-8.x/custom-android-back-button-handling.md index 4d709edb960..03532df8dd2 100755 --- a/versioned_docs/version-8.x/custom-android-back-button-handling.md +++ b/versioned_docs/version-8.x/custom-android-back-button-handling.md @@ -60,7 +60,7 @@ function ScreenWithCustomBackBehavior() { return ( {listData.map((item) => ( - <> + {isSelectionModeEnabled ? ( { @@ -85,7 +85,7 @@ function ScreenWithCustomBackBehavior() { {item.key} )} - + ))} ); } @@ -201,7 +200,10 @@ The `useDrawerProgress` hook returns a Reanimated `SharedValue` which represents Example with modern implementation: ```js -import { Animated } from 'react-native-reanimated'; +import Animated, { + interpolate, + useAnimatedStyle, +} from 'react-native-reanimated'; import { useDrawerProgress } from 'react-native-drawer-layout'; // ... @@ -213,7 +215,7 @@ function MyComponent() { return { transform: [ { - translateX: interpolate(progress, [0, 1], [-100, 0]), + translateX: interpolate(progress.value, [0, 1], [-100, 0]), }, ], }; diff --git a/versioned_docs/version-8.x/drawer-navigator.md b/versioned_docs/version-8.x/drawer-navigator.md index e9946cbb780..418c465c5ff 100644 --- a/versioned_docs/version-8.x/drawer-navigator.md +++ b/versioned_docs/version-8.x/drawer-navigator.md @@ -501,7 +501,7 @@ Type of the drawer. It determines how the drawer looks and animates. Defaults to `slide` on iOS and `front` on other platforms. -You can conditionally specify the `drawerType` to show a permanent drawer on bigger screens and a traditional drawer drawer on small screens: +You can conditionally specify the `drawerType` to show a permanent drawer on bigger screens and a traditional drawer on small screens: ```js import { useWindowDimensions } from 'react-native'; @@ -541,7 +541,6 @@ import { const MyDrawer = createDrawerNavigator({ defaultStatus: 'open', - layout: ({ children }) => {children}, screenOptions: { drawerType: 'back', drawerStyle: { width: '100%' }, @@ -568,10 +567,10 @@ const MyDrawer = createDrawerNavigator({ }, screens: { Home: createDrawerScreen({ - component: HomeScreen, + screen: HomeScreen, }), Profile: createDrawerScreen({ - component: ProfileScreen, + screen: ProfileScreen, }), }, }); diff --git a/versioned_docs/version-8.x/elements.md b/versioned_docs/version-8.x/elements.md index d6ff6a7d46a..a1d2f85f426 100644 --- a/versioned_docs/version-8.x/elements.md +++ b/versioned_docs/version-8.x/elements.md @@ -251,14 +251,17 @@ const RootStack = createNativeStackNavigator({ screen: HomeScreen, options: { headerLeft: (props) => ( - { - // Do something - }}> - ) - } - } - } -}) + { + // Do something + }} + /> + ), + }, + }, + }, +}); ``` @@ -303,15 +306,18 @@ const RootStack = createNativeStackNavigator({ Home: { screen: HomeScreen, options: { - headerLeft: (props) => ( - { - // Do something - }}> - ) - } - } - } -}) + headerRight: (props) => ( + { + // Do something + }} + /> + ), + }, + }, + }, +}); ``` @@ -322,7 +328,7 @@ const RootStack = createNativeStackNavigator({ name="Home" component={HomeScreen} options={{ - headerLeft: (props) => ( + headerRight: (props) => ( { @@ -816,7 +822,7 @@ Usage: ### `SafeAreaProviderCompat` -A wrapper over the `SafeAreaProvider` component from [`react-native-safe-area-context](https://github.com/th3rdwave/react-native-safe-area-context) which includes initial values. +A wrapper over the `SafeAreaProvider` component from [`react-native-safe-area-context`](https://github.com/th3rdwave/react-native-safe-area-context) which includes initial values. Usage: diff --git a/versioned_docs/version-8.x/group.md b/versioned_docs/version-8.x/group.md index c79783805a7..3e1f0394530 100644 --- a/versioned_docs/version-8.x/group.md +++ b/versioned_docs/version-8.x/group.md @@ -68,7 +68,7 @@ const MyStack = createNativeStackNavigator({ }); // codeblock-focus-end -const Navigation = createStaticNavigation(Stack); +const Navigation = createStaticNavigation(MyStack); export default function App() { return ; diff --git a/versioned_docs/version-8.x/handling-safe-area.md b/versioned_docs/version-8.x/handling-safe-area.md index b632c672d8f..6f43a24f8c5 100755 --- a/versioned_docs/version-8.x/handling-safe-area.md +++ b/versioned_docs/version-8.x/handling-safe-area.md @@ -407,7 +407,7 @@ import * as React from 'react'; import { Text, View } from 'react-native'; import { NavigationContainer } from '@react-navigation/native'; import { createBottomTabNavigator } from '@react-navigation/bottom-tabs'; -import { createStackNavigator } from '@react-navigation/stack'; +import { createNativeStackNavigator } from '@react-navigation/native-stack'; // codeblock-focus-start import { SafeAreaProvider, @@ -434,7 +434,7 @@ function Demo() { } // codeblock-focus-end -const Stack = createStackNavigator(); +const Stack = createNativeStackNavigator(); const Tab = createBottomTabNavigator(); export default function App() { diff --git a/versioned_docs/version-8.x/headers.md b/versioned_docs/version-8.x/headers.md index ae93927f041..7fc2e940a3c 100755 --- a/versioned_docs/version-8.x/headers.md +++ b/versioned_docs/version-8.x/headers.md @@ -147,7 +147,10 @@ import { createStaticNavigation, useNavigation, } from '@react-navigation/native'; -import { createNativeStackNavigator } from '@react-navigation/native-stack'; +import { + createNativeStackNavigator, + createNativeStackScreen, +} from '@react-navigation/native-stack'; import { Button } from '@react-navigation/elements'; function HomeScreen() { @@ -200,7 +203,10 @@ There are three key properties to use when customizing the style of your header: import * as React from 'react'; import { Text, View } from 'react-native'; import { createStaticNavigation } from '@react-navigation/native'; -import { createNativeStackNavigator } from '@react-navigation/native-stack'; +import { + createNativeStackNavigator, + createNativeStackScreen, +} from '@react-navigation/native-stack'; function HomeScreen() { return ( @@ -261,7 +267,10 @@ import { createStaticNavigation, useNavigation, } from '@react-navigation/native'; -import { createNativeStackNavigator } from '@react-navigation/native-stack'; +import { + createNativeStackNavigator, + createNativeStackScreen, +} from '@react-navigation/native-stack'; import { Button } from '@react-navigation/elements'; function HomeScreen() { @@ -320,7 +329,7 @@ All screens in this navigator will now share these styles. Individual screens ca ## Replacing the title with a custom component -Sometimes you need more control than just changing the text and styles of your title -- for example, you may want to render an image in place of the title, or make the title into a button. In these cases, you can completely override the component used for the title and provide your own. +Sometimes you need more control than just changing the text and styles of your title - for example, you may want to render an image in place of the title, or make the title into a button. In these cases, you can completely override the component used for the title and provide your own. ```js name="Custom title" snack static2dynamic import * as React from 'react'; diff --git a/versioned_docs/version-8.x/hello-react-navigation.md b/versioned_docs/version-8.x/hello-react-navigation.md index 1adee185d7f..1a65c3d7365 100755 --- a/versioned_docs/version-8.x/hello-react-navigation.md +++ b/versioned_docs/version-8.x/hello-react-navigation.md @@ -145,7 +145,7 @@ If you run this code, you will see a screen with an empty navigation bar and a g :::tip -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 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. ::: diff --git a/versioned_docs/version-8.x/material-top-tab-navigator.md b/versioned_docs/version-8.x/material-top-tab-navigator.md index d3751d33fc1..741a3a865d6 100755 --- a/versioned_docs/version-8.x/material-top-tab-navigator.md +++ b/versioned_docs/version-8.x/material-top-tab-navigator.md @@ -151,7 +151,7 @@ String indicating whether the keyboard gets dismissed in response to a drag gest - `'on-drag'`: the keyboard is dismissed when a drag begins. - `'none'`: drags do not dismiss the keyboard. -##### `overScrollMode` +#### `overScrollMode` Used to override default value of pager's overScroll mode. @@ -169,7 +169,7 @@ Object containing the initial height and width of the screens. Passing this will ```js { - width: Dimensions.get('window').width; + width: Dimensions.get('window').width, } ``` diff --git a/versioned_docs/version-8.x/modal.md b/versioned_docs/version-8.x/modal.md index 39811924663..b7e5d5fadd3 100755 --- a/versioned_docs/version-8.x/modal.md +++ b/versioned_docs/version-8.x/modal.md @@ -108,9 +108,9 @@ export default function App() { -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. +Here, we are creating 2 groups of screens. 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), `modal`, or `transparentModal`. 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`. +Instead of specifying this option for a group, it's also possible to specify it for a single screen using the `options` property. ## Summary diff --git a/versioned_docs/version-8.x/more-resources.md b/versioned_docs/version-8.x/more-resources.md index 8e71db8cf3a..a3969e235db 100755 --- a/versioned_docs/version-8.x/more-resources.md +++ b/versioned_docs/version-8.x/more-resources.md @@ -6,6 +6,8 @@ sidebar_label: More resources ## Talks +These are historical talks from earlier React Navigation versions. + - [Mobile App Development with React Native at Harvard Extension School](https://cs50.harvard.edu/mobile/2018/): Lecture 6 covers React Navigation, includes exercises, slides, and video. - [Mobile Navigation at React Alicante](https://www.youtube.com/watch?v=GBhdooVxX6Q): An overview and comparison of the approaches taken by react-native-navigation and react-navigation. diff --git a/versioned_docs/version-8.x/multiple-drawers.md b/versioned_docs/version-8.x/multiple-drawers.md index d236c9ede34..66347bcf8f9 100644 --- a/versioned_docs/version-8.x/multiple-drawers.md +++ b/versioned_docs/version-8.x/multiple-drawers.md @@ -202,11 +202,13 @@ export default function App() { 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-object.md#getparent) to refer to the right drawer which is the parent of the left drawer. So our code would look like: +To solve this, we need to use [`navigation.getParent`](navigation-object.md#getparent) to refer to the right drawer, which is the parent of the left drawer. So our code would look like: ```js - - + + ``` However, this means that our button needs to know about the parent navigators, which isn't ideal. If our button is further nested inside other navigators, it'd need multiple `getParent()` calls. To solve this, we can pass the name of the screen where the navigator is to the `getParent` method to directly refer to the desired navigator. diff --git a/versioned_docs/version-8.x/native-stack-navigator.md b/versioned_docs/version-8.x/native-stack-navigator.md index f3bfc867d3f..f6af9ad88f3 100755 --- a/versioned_docs/version-8.x/native-stack-navigator.md +++ b/versioned_docs/version-8.x/native-stack-navigator.md @@ -154,7 +154,7 @@ Supported values: - `"none"` - `"slide"` -On Android, setting either `fade` or `slide` will set the transition of status bar color. On iOS, this option applies to the appereance animation of the status bar. +On Android, setting either `fade` or `slide` will set the transition of status bar color. On iOS, this option applies to the appearance animation of the status bar. Requires setting `View controller-based status bar appearance -> YES` (or removing the config) in your `Info.plist` file. @@ -1379,9 +1379,9 @@ The native stack navigator exports the following hooks: #### `useAnimatedHeaderHeight` -The hook returns an animated value representing the height of the header. This is similar to [`useHeaderHeight`](elements.md#useheaderheight) but returns an animated value that changed as the header height changes, e.g. when expanding or collapsing large title or search bar on iOS. +The hook returns an animated value representing the height of the header. This is similar to [`useHeaderHeight`](elements.md#useheaderheight) but returns an animated value that changes as the header height changes, e.g. when expanding or collapsing large title or search bar on iOS. -It can be used to animated content along with header height changes. +It can be used to animate content along with header height changes. ```js import { Animated } from 'react-native'; diff --git a/versioned_docs/version-8.x/navigating-without-navigation-prop.md b/versioned_docs/version-8.x/navigating-without-navigation-prop.md index 0200c83209a..4c130707c5f 100755 --- a/versioned_docs/version-8.x/navigating-without-navigation-prop.md +++ b/versioned_docs/version-8.x/navigating-without-navigation-prop.md @@ -7,7 +7,7 @@ sidebar_label: Navigation Ref import Tabs from '@theme/Tabs'; import TabItem from '@theme/TabItem'; -Sometimes you need to trigger a navigation action from places where you do not have access to the `navigation` object, such as a Redux middleware. For such cases, you can dispatch navigation actions use a [`ref` on the navigation container](navigation-container.md#ref). +Sometimes you need to trigger a navigation action from places where you do not have access to the `navigation` object, such as a Redux middleware. For such cases, you can dispatch navigation actions using a [`ref` on the navigation container](navigation-container.md#ref). **Do not** use the `ref` if: @@ -76,7 +76,7 @@ export function navigate(name, params) { // add other navigation functions that you need and export them ``` -Then, in any of your javascript modules, import the `RootNavigation` and call functions which you exported from it. You may use this approach outside of your React components and, in fact, it works as well when used from within them. +Then, in any of your javascript modules, import the `RootNavigation` and call functions which you exported from it. You may use this approach outside of your React components. @@ -227,7 +227,7 @@ When writing tests, you may mock the navigation functions, and make assertions o ## Handling initialization -When using this pattern, you need to keep few things in mind to avoid navigation from failing in your app. +When using this pattern, you need to keep a few things in mind to avoid navigation from failing in your app. - The `ref` is set only after the navigation container renders, this can be async when handling deep links - A navigator needs to be rendered to be able to handle actions, the `ref` won't be ready without a navigator @@ -356,4 +356,4 @@ export default function App() { -If you're unsure if a navigator is rendered, you can call `navigationRef.current.getRootState()`, and it'll return a valid state object if any navigators are rendered, otherwise it will return `undefined`. +If you're unsure if a navigator is rendered, you can call `navigationRef.getRootState()`, and it'll return a valid state object if any navigators are rendered, otherwise it will return `undefined`. diff --git a/versioned_docs/version-8.x/navigation-actions.md b/versioned_docs/version-8.x/navigation-actions.md index 7e6250ebfb1..9466c167633 100755 --- a/versioned_docs/version-8.x/navigation-actions.md +++ b/versioned_docs/version-8.x/navigation-actions.md @@ -12,7 +12,7 @@ A navigation action is an object containing at least a `type` property. Internal Each navigation actions can contain at least the following properties: - `type` (required) - A string that represents the name of the action. -- `payload` (options) - An object containing additional information about the action. For example, it will contain `name` and `params` for `navigate`. +- `payload` (optional) - An object containing additional information about the action. For example, it will contain `name` and `params` for `navigate`. - `source` (optional) - The key of the route which should be considered as the source of the action. This is used for some actions to determine which route to apply the action on. By default, `navigation.dispatch` adds the key of the route that dispatched the action. - `target` (optional) - The key of the [navigation state](navigation-state.md) the action should be applied on. @@ -113,7 +113,7 @@ In a stack navigator ([stack](stack-navigator.md) or [native stack](native-stack
Advanced usage -The `navigate` action can also accepts an object as the argument with the following properties: +The `navigate` action can also accept an object as the argument with the following properties: - `name` - _string_ - A destination name of the screen in the current or a parent navigator - `params` - _object_ - Params to use for the destination route. @@ -188,7 +188,7 @@ function ProfileScreen({ route }) { routes: [ { name: 'Profile', - params: { user: 'jane', key: route.params.key }, + params: { user: 'jane' }, }, { name: 'Home' }, ], @@ -529,7 +529,7 @@ When a screen is preloaded in a stack navigator, it can't dispatch navigation ac ### setParams -The `setParams` action allows to replace params for a certain route. It takes the following arguments: +The `setParams` action allows to merge params for a certain route. It takes the following arguments: - `params` - _object_ - required - New params to be merged into existing route params. @@ -941,9 +941,7 @@ function SettingsScreen() { } const HomeTabs = createBottomTabNavigator({ - screenOptions: { - backBehavior: 'history', - }, + backBehavior: 'history', screens: { ProductList: ProductListScreen, Settings: SettingsScreen, diff --git a/versioned_docs/version-8.x/navigation-container.md b/versioned_docs/version-8.x/navigation-container.md index 08358bcad7b..df914f204c0 100644 --- a/versioned_docs/version-8.x/navigation-container.md +++ b/versioned_docs/version-8.x/navigation-container.md @@ -81,10 +81,14 @@ import { // codeblock-focus-end import { createStackNavigator } from '@react-navigation/stack'; +function EmptyScreen() { + return ; +} + const Stack = createStackNavigator({ initialRouteName: 'Empty', screens: { - Empty: () => , + Empty: EmptyScreen, Home: HomeScreen, }, }); @@ -140,6 +144,10 @@ function HomeScreen() { ); } +function EmptyScreen() { + return ; +} + // codeblock-focus-start export default function App() { @@ -151,7 +159,7 @@ export default function App() { - } /> + @@ -537,7 +545,7 @@ Example: ```js ```js -const Tab = createBottomTabNavigatior({ +const Tab = createBottomTabNavigator({ screens: { Chat: { screen: Chat, @@ -338,7 +338,7 @@ Example: ```js -const Tab = createBottomTabNavigatior({ +const Tab = createBottomTabNavigator({ screens: { Chat: { screen: Chat, @@ -436,7 +436,7 @@ Similar to `listeners`, you can also pass a function to `screenListeners`. The f ```js -const Tab = createBottomTabNavigatior({ +const Tab = createBottomTabNavigator({ screenListeners: ({ navigation }) => ({ state: (e) => { // Do something with the state diff --git a/versioned_docs/version-8.x/navigation-lifecycle.md b/versioned_docs/version-8.x/navigation-lifecycle.md index 9f45ad21784..ecab09e112b 100755 --- a/versioned_docs/version-8.x/navigation-lifecycle.md +++ b/versioned_docs/version-8.x/navigation-lifecycle.md @@ -262,7 +262,7 @@ export default function App() { See [Navigation events](navigation-events.md) for more details. -For performing side effects, we can use the [`useFocusEffect`](use-focus-effect.md) - it's like `useEffect` but ties to the navigation lifecycle -- it runs the effect when the screen comes into focus and cleans it up when the screen goes out of focus: +For performing side effects, we can use the [`useFocusEffect`](use-focus-effect.md) - it's like `useEffect` but ties to the navigation lifecycle - it runs the effect when the screen comes into focus and cleans it up when the screen goes out of focus: ```js name="Focus effect" snack static2dynamic import * as React from 'react'; diff --git a/versioned_docs/version-8.x/navigation-object.md b/versioned_docs/version-8.x/navigation-object.md index 34a93483dc8..cc9bdd96dc6 100755 --- a/versioned_docs/version-8.x/navigation-object.md +++ b/versioned_docs/version-8.x/navigation-object.md @@ -221,7 +221,7 @@ function ProfileScreen({ route }) { {route.params.names[0]} {route.params.names[1]} {route.params.names[2]} - + ); } @@ -459,7 +459,7 @@ function HomeScreen() { }); }} > - Go to Brents profile + Go to Brent's profile ); @@ -509,7 +509,7 @@ function ProfileScreen({ route }) { > Reset navigator state to Settings - + ); @@ -595,7 +595,7 @@ function HomeScreen() { }); }} > - Go to Brents profile + Go to Brent's profile ); @@ -645,12 +645,11 @@ function ProfileScreen({ route }) { > Reset navigator state to Settings - + ); @@ -678,7 +677,7 @@ function SettingsScreen({ route }) { }); }} > - Go to Brents profile + Go to Brent's profile ); @@ -955,7 +954,7 @@ function HomeScreen() { }); }} > - Go to Brents profile + Go to Brent's profile ); @@ -1054,7 +1053,7 @@ function HomeScreen() { }); }} > - Go to Brents profile + Go to Brent's profile ); @@ -1163,7 +1162,7 @@ function HomeScreen() { }); }} > - Go to Brents profile + Go to Brent's profile ); @@ -1262,7 +1261,7 @@ function HomeScreen() { }); }} > - Go to Brents profile + Go to Brent's profile ); @@ -1725,7 +1724,7 @@ This method lets us check whether the screen is currently focused. Returns `true const isFocused = navigation.isFocused(); ``` -This method doesn't re-render the screen when the value changes and mainly useful in callbacks. You probably want to use [useIsFocused](use-is-focused.md) instead of using this directly, it will return a boolean a prop to indicating if the screen is focused. +This method doesn't re-render the screen when the value changes and is mainly useful in callbacks. You probably want to use [useIsFocused](use-is-focused.md) instead of using this directly, as the hook re-renders the screen when focus changes. ## Advanced API Reference @@ -1762,8 +1761,8 @@ import { CommonActions } from '@react-navigation/native'; navigation.dispatch({ ...CommonActions.navigate('Profile'), - source: 'someRoutekey', - target: 'someStatekey', + source: 'someRouteKey', + target: 'someStateKey', }); ``` @@ -1856,7 +1855,7 @@ const RootDrawer = createDrawerNavigator({ }); ``` -Then when using `getParent` inside of `FeedScree`, instead of: +Then when using `getParent` inside of `FeedScreen`, instead of: ```js // Avoid this diff --git a/versioned_docs/version-8.x/nesting-navigators.md b/versioned_docs/version-8.x/nesting-navigators.md index 714b860c185..c78d7af9cbf 100755 --- a/versioned_docs/version-8.x/nesting-navigators.md +++ b/versioned_docs/version-8.x/nesting-navigators.md @@ -16,8 +16,14 @@ import { createStaticNavigation, useNavigation, } from '@react-navigation/native'; -import { createNativeStackNavigator } from '@react-navigation/native-stack'; -import { createBottomTabNavigator } from '@react-navigation/bottom-tabs'; +import { + createNativeStackNavigator, + createNativeStackScreen, +} from '@react-navigation/native-stack'; +import { + createBottomTabNavigator, + createBottomTabScreen, +} from '@react-navigation/bottom-tabs'; import { Button } from '@react-navigation/elements'; function ProfileScreen() { @@ -100,7 +106,7 @@ When nesting navigators, there are some things to keep in mind: ### Each navigator keeps its own navigation history -Lets say you have a stack navigator (lets call it `StackA`) nested within another navigator (lets call it `NavigatorB`). When you press the back button in a screen inside `StackA`, it will go to the previous screen of the closest ancestor navigator of the screen - i.e. `StackA`. +Let's say you have a stack navigator (let's call it `StackA`) nested within another navigator (let's call it `NavigatorB`). When you press the back button in a screen inside `StackA`, it will go to the previous screen of the closest ancestor navigator of the screen - i.e. `StackA`. If the current screen is the first screen in `StackA`, then pressing back will go to the previous screen in `NavigatorB`. @@ -805,7 +811,7 @@ const HomeTabs = createBottomTabNavigator({ }, }); -const RootStack = createStackNavigator({ +const RootStack = createNativeStackNavigator({ // highlight-start screenOptions: { headerShown: false, @@ -870,7 +876,7 @@ Think of nesting navigators as a way to achieve the UI you want, not as a way to ```js -const MyStack = createStackNavigator({ +const MyStack = createNativeStackNavigator({ screens: { // Common screens }, diff --git a/versioned_docs/version-8.x/params.md b/versioned_docs/version-8.x/params.md index c18ed75675e..85950b12a3f 100755 --- a/versioned_docs/version-8.x/params.md +++ b/versioned_docs/version-8.x/params.md @@ -163,11 +163,13 @@ You can specify default params for a screen using `initialParams`. These are use ```js -createNativeStackScreen({ - Details: { - screen: DetailsScreen, - // highlight-next-line - initialParams: { itemId: 42 }, +const RootStack = createNativeStackNavigator({ + screens: { + Details: createNativeStackScreen({ + screen: DetailsScreen, + // highlight-next-line + initialParams: { itemId: 42 }, + }), }, }); ``` diff --git a/versioned_docs/version-8.x/route-object.md b/versioned_docs/version-8.x/route-object.md index 346af1b4ed1..246ad06f908 100755 --- a/versioned_docs/version-8.x/route-object.md +++ b/versioned_docs/version-8.x/route-object.md @@ -7,13 +7,13 @@ sidebar_label: Route object import Tabs from '@theme/Tabs'; import TabItem from '@theme/TabItem'; -Each `screen` component in your app is provided with the `route` object as a prop automatically. The prop contains various information regarding current route (place in navigation hierarchy component lives). +Each `screen` component in your app is provided with the `route` object as a prop automatically. The prop contains information about the current route. - `route` - `key` - Unique key of the screen. Created automatically or added while navigating to this screen. - `name` - Name of the screen. Defined in navigator component hierarchy. - - `path` - An optional string containing the path that opened the screen, exists when the screen was opened via a deep link. - - `params` - An optional object containing params which is defined while navigating e.g. `navigate('Twitter', { user: 'Dan Abramov' })`. + - `path` - An optional string containing the path that opened the screen. It exists when the screen was opened via a deep link. + - `params` - An optional object containing params defined while navigating, e.g. `navigate('Twitter', { user: 'Jane Doe' })`. @@ -26,7 +26,10 @@ import { createNativeStackNavigator } from '@react-navigation/native-stack'; const Stack = createNativeStackNavigator({ screens: { - Profile: ProfileScreen, + Profile: { + screen: ProfileScreen, + initialParams: { user: 'Jane Doe' }, + }, }, }); @@ -36,6 +39,8 @@ function ProfileScreen({ route }) { This is the profile screen of the app {route.name} + {route.path ?? 'No path'} + {route.params?.user ?? 'No params'} ); } @@ -65,6 +70,8 @@ function ProfileScreen({ route }) { This is the profile screen of the app {route.name} + {route.path ?? 'No path'} + {route.params?.user ?? 'No params'} ); } @@ -74,7 +81,11 @@ export default function App() { return ( - + ); diff --git a/versioned_docs/version-8.x/screen-options-resolution.md b/versioned_docs/version-8.x/screen-options-resolution.md index 73d41ddfbd3..bb7cddae844 100755 --- a/versioned_docs/version-8.x/screen-options-resolution.md +++ b/versioned_docs/version-8.x/screen-options-resolution.md @@ -180,7 +180,7 @@ const Tab = createBottomTabNavigator({ }, }, }); -// codeblock-focus-start +// codeblock-focus-end const Navigation = createStaticNavigation(Tab); diff --git a/versioned_docs/version-8.x/screen-options.md b/versioned_docs/version-8.x/screen-options.md index 45da3c35ef6..ed2e0f4f39b 100644 --- a/versioned_docs/version-8.x/screen-options.md +++ b/versioned_docs/version-8.x/screen-options.md @@ -88,9 +88,9 @@ const RootStack = createNativeStackNavigator({ screen: HomeScreen, options: ({ navigation }) => ({ title: 'Awesome app', - headerLeft: () => { - navigation.toggleDrawer()} />; - }, + headerLeft: () => ( + + ), }), }), }, @@ -246,10 +246,12 @@ const Stack = createNativeStackNavigator({ }, groups: { Modal: { - screenOptions: { + screenOptions: ({ navigation }) => ({ presentation: 'modal', - headerLeft: () => , - }, + headerLeft: () => ( + + ), + }), screens: { Settings: createNativeStackScreen({ screen: Settings, @@ -273,7 +275,9 @@ const Stack = createNativeStackNavigator({ ({ presentation: 'modal', - headerLeft: () => , + headerLeft: () => ( + + ), })} > diff --git a/versioned_docs/version-8.x/screen-tracking.md b/versioned_docs/version-8.x/screen-tracking.md index d0171fe0b18..b0453af405d 100644 --- a/versioned_docs/version-8.x/screen-tracking.md +++ b/versioned_docs/version-8.x/screen-tracking.md @@ -74,18 +74,15 @@ export default function App() { return ( { + onReady={async () => { routeNameRef.current = navigationRef.current.getCurrentRoute().name; // Replace the line below to add the tracker from a mobile analytics SDK - await trackScreenView(currentRouteName); + await trackScreenView(routeNameRef.current); }} onStateChange={async () => { const previousRouteName = routeNameRef.current; const currentRouteName = navigationRef.current.getCurrentRoute().name; - const trackScreenView = () => { - // Your implementation of analytics goes here! - }; if (previousRouteName !== currentRouteName) { // Replace the line below to add the tracker from a mobile analytics SDK @@ -150,7 +147,7 @@ export default function App() { return ( { + onReady={async () => { routeNameRef.current = navigationRef.current.getCurrentRoute().name; // Replace the line below to add the tracker from a mobile analytics SDK @@ -159,9 +156,6 @@ export default function App() { onStateChange={async () => { const previousRouteName = routeNameRef.current; const currentRouteName = navigationRef.current.getCurrentRoute().name; - const trackScreenView = () => { - // Your implementation of analytics goes here! - }; if (previousRouteName !== currentRouteName) { // Replace the line below to add the tracker from a mobile analytics SDK diff --git a/versioned_docs/version-8.x/server-container.md b/versioned_docs/version-8.x/server-container.md index 655b158feac..ac22ef72181 100644 --- a/versioned_docs/version-8.x/server-container.md +++ b/versioned_docs/version-8.x/server-container.md @@ -12,8 +12,8 @@ Example: // Ref which will be populated with the screen options const ref = React.createRef(); -// Location object containing the `pathname` and `search` fields of the current URL -const location = { pathname: '/profile', search: '?user=jane' }; +// Location object - can be a URL object or an object with `pathname` and `search` fields +const location = new URL('/profile?user=jane', 'https://example.org/'); // Get rendered HTML const html = ReactDOMServer.renderToString( @@ -23,10 +23,10 @@ const html = ReactDOMServer.renderToString( ); // Then you can access the options for the current screen in the ref -const options = ref.current.getCurrentOptions(); // { title: 'My Profile' } +const options = ref.current?.getCurrentOptions(); // { title: 'My Profile' } ``` -The `ServerContainer` component should wrap your entire app during server rendering. Note that you still need a `NavigationContainer` in your app, `ServerContainer` doesn't replace it.' +The `ServerContainer` component should wrap your entire app during server rendering. Note that you still need a `NavigationContainer` in your app, `ServerContainer` doesn't replace it. See the [`server rendering guide`](server-rendering.md) for a detailed guide and examples. diff --git a/versioned_docs/version-8.x/server-rendering.md b/versioned_docs/version-8.x/server-rendering.md index 0850ff1404e..6efc221b868 100644 --- a/versioned_docs/version-8.x/server-rendering.md +++ b/versioned_docs/version-8.x/server-rendering.md @@ -61,7 +61,7 @@ Here, `./src/App` is the file where you have `AppRegistry.registerComponent('App If you're using React Navigation in your app, this will render the screens rendered by your home page. However, if you have [configured links](configuring-links.md) in your app, you'd want to render the correct screens for the request URL on server so that it matches what'll be rendered on the client. -We can use the [`ServerContainer`](server-container.md) to do that by passing this info in the `location` prop. For example, with Koa, you can use the `path` and `search` properties from the context argument: +We can use the [`ServerContainer`](server-container.md) to do that by passing this info in the `location` prop. For example, with Koa, you can create a `URL` object from `ctx.url`: ```js app.use(async (ctx) => { @@ -103,13 +103,10 @@ app.use(async (ctx) => { const { element, getStyleElement } = AppRegistry.getApplication('App'); - const ref = React.createRef(); + const ref = React.createRef(); const html = ReactDOMServer.renderToString( - + {element} ); @@ -128,7 +125,7 @@ app.use(async (ctx) => { content="width=device-width, initial-scale=1, minimum-scale=1, maximum-scale=1.00001, viewport-fit=cover" > ${css} - ${options.title} + ${options?.title ?? 'My App'}
${html} @@ -252,5 +249,5 @@ You can follow a similar approach for other status codes too, for example, `401` ## Summary - Use the `location` prop on `ServerContainer` to render correct screens based on the incoming request. -- Attach a `ref` to the `ServerContainer` get options for the current screen. +- Attach a `ref` to the `ServerContainer` to get options for the current screen. - Use context to attach more information such as status code. diff --git a/versioned_docs/version-8.x/stack-actions.md b/versioned_docs/version-8.x/stack-actions.md index 00d9f945b42..bce716efb4f 100755 --- a/versioned_docs/version-8.x/stack-actions.md +++ b/versioned_docs/version-8.x/stack-actions.md @@ -389,7 +389,7 @@ export default function App() { ## popToTop -The `popToTop` action takes you back to the first screen in the stack, dismissing all the others. It's functionally identical to `StackActions.pop({n: currentIndex})`. +The `popToTop` action takes you back to the first screen in the stack, dismissing all the others. ```js name="Stack actions popToTop" snack static2dynamic import * as React from 'react'; diff --git a/versioned_docs/version-8.x/stack-navigator.md b/versioned_docs/version-8.x/stack-navigator.md index 6c5e74ff66c..af06d0dc878 100755 --- a/versioned_docs/version-8.x/stack-navigator.md +++ b/versioned_docs/version-8.x/stack-navigator.md @@ -674,6 +674,7 @@ Stack Navigator exposes various options to configure the transition animation wh useNavigation, } from '@react-navigation/native'; import { Button } from '@react-navigation/elements'; + import { Animated } from 'react-native'; import { createStackNavigator } from '@react-navigation/stack'; function HomeScreen() { @@ -774,6 +775,7 @@ Stack Navigator exposes various options to configure the transition animation wh useNavigation, } from '@react-navigation/native'; import { Button } from '@react-navigation/elements'; + import { Animated } from 'react-native'; import { createStackNavigator } from '@react-navigation/stack'; function HomeScreen() { @@ -902,7 +904,7 @@ const forSlide = ({ current, next, inverted, layouts: { screen } }) => { - `titleStyle` - Style for the header title text. - `backgroundStyle` - Style for the header background. - The function receives the following properties in it's argument: + The function receives the following properties in its argument: - `current` - Values for the current screen (the screen which owns this header). - `progress` - Animated node representing the progress value of the current screen. `0` when screen should start coming into view, `0.5` when it's mid-way, `1` when it should be fully in view. - `next` - Values for the screen after this one in the stack. This can be `undefined` in case the screen animating is the last one. @@ -943,6 +945,7 @@ const forSlide = ({ current, next, inverted, layouts: { screen } }) => { useNavigation, } from '@react-navigation/native'; import { Button } from '@react-navigation/elements'; + import { Animated } from 'react-native'; import { createStackNavigator } from '@react-navigation/stack'; function HomeScreen() { diff --git a/versioned_docs/version-8.x/static-configuration.md b/versioned_docs/version-8.x/static-configuration.md index a10894b97e8..35a135cd6ed 100644 --- a/versioned_docs/version-8.x/static-configuration.md +++ b/versioned_docs/version-8.x/static-configuration.md @@ -84,7 +84,7 @@ The `screens` object can contain key value pairs where the key is the name of th The `groups` object can contain key-value pairs where the key is the name of the group and the value is the group configuration. -The configuration object for a screen accepts the [properties described in the Group page](group.md). In addition, the following properties are available when using static configuration: +The configuration object for a group accepts the [properties described in the Group page](group.md). In addition, the following properties are available when using static configuration: - `if` - this can be used to conditionally render the group and works the same as the [`if` property in the screen configuration](#if). - `screens` - an object containing configuration for each screen in the group. The configuration is the same as the [`screens` object in the navigator configuration](#screens). diff --git a/versioned_docs/version-8.x/static-vs-dynamic.md b/versioned_docs/version-8.x/static-vs-dynamic.md index b3c5de4f792..e7a95f9dc6c 100644 --- a/versioned_docs/version-8.x/static-vs-dynamic.md +++ b/versioned_docs/version-8.x/static-vs-dynamic.md @@ -148,7 +148,10 @@ All props passed to `` except `name` and `component` become proper ``` ```js title="Static API" -import { createNativeStackScreen } from '@react-navigation/native-stack'; +import { + createNativeStackNavigator, + createNativeStackScreen, +} from '@react-navigation/native-stack'; const RootStack = createNativeStackNavigator({ screens: { @@ -370,7 +373,7 @@ With both approaches, you can access the route params of the parent screen with ## Deep linking -For deep links and dynamic links, the dynamic API requires a linking configuration that maps navigation structure to path patterns. In the static API, deep linking is automatic by default and paths are generated based on the screen name and automatically. Custom path patterns can be defined on each screen's `linking` property: +For deep links and dynamic links, the dynamic API requires a linking configuration that maps navigation structure to path patterns. In the static API, deep linking is automatic by default and paths are generated based on the screen name. Custom path patterns can be defined on each screen's `linking` property: ```js title="Dynamic API" const linking = { diff --git a/versioned_docs/version-8.x/status-bar.md b/versioned_docs/version-8.x/status-bar.md index ee5c2498143..10a55ca06c7 100755 --- a/versioned_docs/version-8.x/status-bar.md +++ b/versioned_docs/version-8.x/status-bar.md @@ -114,10 +114,7 @@ import { View, Text, StatusBar, StyleSheet } from 'react-native'; import { NavigationContainer, useNavigation } from '@react-navigation/native'; import { createNativeStackNavigator } from '@react-navigation/native-stack'; import { Button } from '@react-navigation/elements'; -import { - SafeAreaProvider, - useSafeAreaInsets, -} from 'react-native-safe-area-context'; +import { useSafeAreaInsets } from 'react-native-safe-area-context'; function Screen1() { const navigation = useNavigation('Screen1'); @@ -179,14 +176,12 @@ const Stack = createNativeStackNavigator(); export default function App() { return ( - - - - - - - - + + + + + + ); } @@ -340,10 +335,7 @@ import { useIsFocused } from '@react-navigation/native'; import { NavigationContainer, useNavigation } from '@react-navigation/native'; import { createNativeStackNavigator } from '@react-navigation/native-stack'; import { Button } from '@react-navigation/elements'; -import { - SafeAreaProvider, - useSafeAreaInsets, -} from 'react-native-safe-area-context'; +import { useSafeAreaInsets } from 'react-native-safe-area-context'; function FocusAwareStatusBar(props) { const isFocused = useIsFocused(); @@ -409,14 +401,12 @@ const Stack = createNativeStackNavigator(); export default function App() { return ( - - - - - - - - + + + + + + ); } diff --git a/versioned_docs/version-8.x/tab-view.md b/versioned_docs/version-8.x/tab-view.md index b292b6b2190..d6c7f695087 100644 --- a/versioned_docs/version-8.x/tab-view.md +++ b/versioned_docs/version-8.x/tab-view.md @@ -226,7 +226,7 @@ If you need to pass additional props, use a custom `renderScene` function: const renderScene = ({ route }) => { switch (route.key) { case 'first': - return ; + return ; case 'second': return ; default: @@ -386,7 +386,7 @@ function MyAdapter({ navigationState, children }: AdapterProps) { Check out the [source code of the built-in adapters](https://github.com/react-navigation/react-navigation/tree/main/packages/react-native-tab-view/src) for reference. -#### `animationEnabled` +##### `animationEnabled` Enables animation when changing tab. By default it's true. diff --git a/versioned_docs/version-8.x/testing.md b/versioned_docs/version-8.x/testing.md index a120a33f665..e8f905ec9f5 100644 --- a/versioned_docs/version-8.x/testing.md +++ b/versioned_docs/version-8.x/testing.md @@ -333,12 +333,12 @@ const SurpriseScreen = () => { const [textVisible, setTextVisible] = useState(false); useEffect(() => { - navigation.addListener('transitionEnd', () => setTextVisible(true)); + return navigation.addListener('transitionEnd', () => setTextVisible(true)); }, [navigation]); return ( - {textVisible ? Surprise! : ''} + {textVisible ? Surprise! : null} ); }; @@ -380,12 +380,12 @@ const SurpriseScreen = () => { const [textVisible, setTextVisible] = useState(false); useEffect(() => { - navigation.addListener('transitionEnd', () => setTextVisible(true)); + return navigation.addListener('transitionEnd', () => setTextVisible(true)); }, [navigation]); return ( - {textVisible ? Surprise! : ''} + {textVisible ? Surprise! : null} ); }; @@ -638,7 +638,7 @@ export function MyTabs() { return ( - + ); } @@ -699,9 +699,9 @@ test('loads data on Pokemon info screen after focus', async () => { render(); const homeTabButton = screen.getByLabelText('Home, tab, 1 of 2'); - const profileTabButton = screen.getByLabelText('Profile, tab, 2 of 2'); + const pokemonTabButton = screen.getByLabelText('Pokemon, tab, 2 of 2'); - await user.press(profileTabButton); + await user.press(pokemonTabButton); expect(screen.getByText('Loading...')).toBeVisible(); @@ -713,7 +713,7 @@ test('loads data on Pokemon info screen after focus', async () => { await act(() => jest.runAllTimers()); - await user.press(profileTabButton); + await user.press(pokemonTabButton); expect(screen.queryByText('Loading...')).not.toBeVisible(); expect(screen.getByText('ditto')).toBeVisible(); @@ -744,9 +744,9 @@ test('loads data on Pokemon info screen after focus', async () => { ); const homeTabButton = screen.getByLabelText('Home, tab, 1 of 2'); - const profileTabButton = screen.getByLabelText('Profile, tab, 2 of 2'); + const pokemonTabButton = screen.getByLabelText('Pokemon, tab, 2 of 2'); - await user.press(profileTabButton); + await user.press(pokemonTabButton); expect(screen.getByText('Loading...')).toBeVisible(); @@ -758,7 +758,7 @@ test('loads data on Pokemon info screen after focus', async () => { await act(() => jest.runAllTimers()); - await user.press(profileTabButton); + await user.press(pokemonTabButton); expect(screen.queryByText('Loading...')).not.toBeVisible(); expect(screen.getByText('ditto')).toBeVisible(); @@ -789,7 +789,12 @@ In a production app, we recommend using a library like [React Query](https://tan To make it easier to test components that don't depend on the navigation structure, we can create a light-weight test navigator: ```js title="TestStackNavigator.js" -import { useNavigationBuilder, StackRouter } from '@react-navigation/native'; +import { + createNavigatorFactory, + useNavigationBuilder, + StackRouter, +} from '@react-navigation/native'; +import { View } from 'react-native'; function TestStackNavigator(props) { const { state, descriptors, NavigationContent } = useNavigationBuilder( diff --git a/versioned_docs/version-8.x/themes.md b/versioned_docs/version-8.x/themes.md index 7e3360be59f..dda280ca309 100755 --- a/versioned_docs/version-8.x/themes.md +++ b/versioned_docs/version-8.x/themes.md @@ -106,6 +106,8 @@ When creating a custom theme, you will need to provide all of these properties. Example theme ```js +import { Platform } from 'react-native'; + const WEB_FONT_STACK = 'system-ui, "Segoe UI", Roboto, Helvetica, Arial, sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol"'; diff --git a/versioned_docs/version-8.x/troubleshooting.md b/versioned_docs/version-8.x/troubleshooting.md index 1186ea690eb..7479635e647 100755 --- a/versioned_docs/version-8.x/troubleshooting.md +++ b/versioned_docs/version-8.x/troubleshooting.md @@ -39,7 +39,7 @@ rm -rf $TMPDIR/metro-bundler-cache-* ### Missing peer dependency -If the module points to an npm package (i.e. the name of the module doesn't with `./`), then it's probably due to a missing dependency. To fix this, install the dependency in your project: +If the module points to an npm package (i.e. the name of the module doesn't start with `./`), then it's probably due to a missing dependency. To fix this, install the dependency in your project: ```bash npm2yarn npm install name-of-the-module @@ -113,7 +113,7 @@ npm install --save-dev typescript ## I'm getting an error "null is not an object (evaluating 'RNGestureHandlerModule.default.Direction')" -This and some similar errors might occur if you have a bare React Native project and the library [`react-native-gesture-handler`](https://github.com/software-mansion/react-native-gesture-handler) library isn't linked. +This and some similar errors might occur if you have a bare React Native project and the library [`react-native-gesture-handler`](https://github.com/software-mansion/react-native-gesture-handler) isn't linked. Linking is automatic from React Native 0.60, so if you have linked the library manually, first unlink it: @@ -133,7 +133,7 @@ Now rebuild the app and test on your device or simulator. ## I'm getting an error "requireNativeComponent: "RNCSafeAreaProvider" was not found in the UIManager" -This and some similar errors might occur if you have a bare React Native project and the library [`react-native-safe-area-context`](https://github.com/th3rdwave/react-native-safe-area-context) library isn't linked. +This and some similar errors might occur if you have a bare React Native project and the library [`react-native-safe-area-context`](https://github.com/th3rdwave/react-native-safe-area-context) isn't linked. Linking is automatic from React Native 0.60, so if you have linked the library manually, first unlink it: @@ -301,7 +301,7 @@ const Stack = createNativeStackNavigator({ , }} @@ -338,7 +338,7 @@ const Stack = createNativeStackNavigator({ (); ``` -If you're using a regular `ref` object, you can pass a generic to the `NavigationContainerRef` type.. +If you're using a regular `ref` object, you can pass a generic to the `NavigationContainerRef` type. Example when using `React.useRef` hook: @@ -821,7 +821,7 @@ export type HomeTabParamList = { export type HomeTabScreenProps = CompositeScreenProps< BottomTabScreenProps, - RootStackScreenProps + RootStackScreenProps<'Home'> >; ``` diff --git a/versioned_docs/version-8.x/upgrading-from-7.x.md b/versioned_docs/version-8.x/upgrading-from-7.x.md index ac38d76b65e..8fd22047bdd 100755 --- a/versioned_docs/version-8.x/upgrading-from-7.x.md +++ b/versioned_docs/version-8.x/upgrading-from-7.x.md @@ -13,7 +13,7 @@ React Navigation 8 is still in pre-release stage. The API may still change befor ::: -This guides lists all the breaking changes and new features in React Navigation 8 that you need to be aware of when upgrading from React Navigation 7. +This guide lists all the breaking changes and new features in React Navigation 8 that you need to be aware of when upgrading from React Navigation 7. ## Dependency changes @@ -607,7 +607,7 @@ See [Stack Navigator](stack-navigator.md#headerbackicon) and [Native Stack Navig #### Stack Navigator now accepts a number for `gestureResponseDistance` -Previously, the `gestureResponseDistance` option in Stack Navigator accepted an object with `horizontal` and `vertical` properties to specify the distance for gestures. Since it's not pssible to have both horizontal and vertical gestures at the same time, it now accepts a number to specify the distance for the current gesture direction: +Previously, the `gestureResponseDistance` option in Stack Navigator accepted an object with `horizontal` and `vertical` properties to specify the distance for gestures. Since it's not possible to have both horizontal and vertical gestures at the same time, it now accepts a number to specify the distance for the current gesture direction: ```diff lang=js - gestureResponseDistance: { horizontal: 50 } @@ -654,7 +654,7 @@ Previously, the linking configuration required a `prefixes` option to specify th Since then, the recommended way to develop with Expo has been to use [Development Builds](https://docs.expo.dev/develop/development-builds/introduction/), which use the app's own URL scheme. So the `prefixes` option is not needed for most use cases. -You can now omit the `prefixes` option in the linking configuration unless you're using Expo Go: +You can now omit the `prefixes` option in the linking configuration: diff --git a/versioned_docs/version-8.x/use-focus-effect.md b/versioned_docs/version-8.x/use-focus-effect.md index ec6d7aae01d..a45c535d46a 100755 --- a/versioned_docs/version-8.x/use-focus-effect.md +++ b/versioned_docs/version-8.x/use-focus-effect.md @@ -54,7 +54,7 @@ export default function App() { :::warning -To avoid the running the effect too often, it's important to wrap the callback in `useCallback` before passing it to `useFocusEffect` as shown in the example. +To avoid running the effect too often, it's important to wrap the callback in `useCallback` before passing it to `useFocusEffect` as shown in the example. ::: @@ -138,7 +138,7 @@ useFocusEffect( ); ``` -The cleanup function runs whenever the effect needs to cleanup, i.e. on `blur`, unmount, dependency change etc. It's not a good place to update the state or do something that should happen on `blur`. You should use listen to the `blur` event instead: +The cleanup function runs whenever the effect needs to cleanup, i.e. on `blur`, unmount, dependency change etc. It's not a good place to update the state or do something that should happen on `blur`. You should use the `blur` event instead: ```js React.useEffect(() => { diff --git a/versioned_docs/version-8.x/use-link-builder.md b/versioned_docs/version-8.x/use-link-builder.md index dcb3da963f7..b16bd2f949d 100644 --- a/versioned_docs/version-8.x/use-link-builder.md +++ b/versioned_docs/version-8.x/use-link-builder.md @@ -22,8 +22,9 @@ import { PlatformPressable } from '@react-navigation/elements'; function DrawerContent({ state, descriptors, navigation }) { const { buildHref } = useLinkBuilder(); - return state.routes((route) => ( + return state.routes.map((route) => ( navigation.navigate(route.name, route.params)} > @@ -45,12 +46,13 @@ There are couple of important things to note: The `buildAction` method lets us parse a `href` string into an action object that can be used with [`navigation.dispatch`](navigation-object.md#dispatch) to navigate to the relevant screen. ```js -import { Link, CommonActions, useLinkBuilder } from '@react-navigation/native'; +import { useNavigation, useLinkBuilder } from '@react-navigation/native'; import { Button } from '@react-navigation/elements'; // ... function MyComponent() { + const navigation = useNavigation(); const { buildAction } = useLinkBuilder(); return ( diff --git a/versioned_docs/version-8.x/use-link-props.md b/versioned_docs/version-8.x/use-link-props.md index 9a1834fa9ce..96c26eb01c4 100644 --- a/versioned_docs/version-8.x/use-link-props.md +++ b/versioned_docs/version-8.x/use-link-props.md @@ -103,7 +103,7 @@ function Home() { action={StackActions.replace('Profile', { id: 'jane' })} href="/users/jane" > - Getting Started + Go to Jane's Profile ); } diff --git a/versioned_docs/version-8.x/use-link-to.md b/versioned_docs/version-8.x/use-link-to.md index e75da45d473..f1696088479 100644 --- a/versioned_docs/version-8.x/use-link-to.md +++ b/versioned_docs/version-8.x/use-link-to.md @@ -7,6 +7,8 @@ sidebar_label: useLinkTo The `useLinkTo` hook lets us navigate to a screen using a path instead of a screen name based on the [`linking` options](navigation-container.md#linking). It returns a function that receives the path to navigate to. ```js +import * as React from 'react'; +import { Button } from '@react-navigation/elements'; import { useLinkTo } from '@react-navigation/native'; // ... @@ -35,10 +37,20 @@ Navigating via `href` strings is not type-safe. If you want to navigate to a scr You can wrap your class component in a function component to use the hook: ```js +import * as React from 'react'; +import { Button } from '@react-navigation/elements'; +import { useLinkTo } from '@react-navigation/native'; + class Home extends React.Component { render() { // Get it from props const { linkTo } = this.props; + + return ( + + ); } } @@ -46,6 +58,6 @@ class Home extends React.Component { export default function (props) { const linkTo = useLinkTo(); - return ; + return ; } ``` diff --git a/versioned_docs/version-8.x/use-navigation-state.md b/versioned_docs/version-8.x/use-navigation-state.md index 897e57d5c57..4f5027064fd 100755 --- a/versioned_docs/version-8.x/use-navigation-state.md +++ b/versioned_docs/version-8.x/use-navigation-state.md @@ -37,7 +37,7 @@ function CurrentRouteDisplay() { // highlight-start const focusedRouteName = useNavigationState( 'Home', - (state) => state.routes[state.index] + (state) => state.routes[state.index].name ); // highlight-end diff --git a/versioned_docs/version-8.x/use-route-path.md b/versioned_docs/version-8.x/use-route-path.md index 530bc324cb7..bcadb6b6a72 100644 --- a/versioned_docs/version-8.x/use-route-path.md +++ b/versioned_docs/version-8.x/use-route-path.md @@ -13,6 +13,7 @@ The `useRoutePath` hook can be used to get the path of a route based on the [`li ```js import { useRoutePath } from '@react-navigation/native'; +import { Text } from 'react-native'; function MyComponent() { const path = useRoutePath(); diff --git a/versioned_docs/version-8.x/use-scroll-to-top.md b/versioned_docs/version-8.x/use-scroll-to-top.md index 9c714c15cbf..a6bfd392929 100755 --- a/versioned_docs/version-8.x/use-scroll-to-top.md +++ b/versioned_docs/version-8.x/use-scroll-to-top.md @@ -9,7 +9,7 @@ import TabItem from '@theme/TabItem'; The expected native behavior of scrollable components is to respond to events from navigation that will scroll to top when tapping on the active tab as you would expect from native tab bars. -In order to achieve it we export `useScrollToTop` which accept ref to scrollable component (e,g. `ScrollView` or `FlatList`). +In order to achieve it we export `useScrollToTop`, which accepts a ref to a scrollable component (e.g. `ScrollView` or `FlatList`). Example: @@ -81,6 +81,10 @@ export default function App() { You can wrap your class component in a function component to use the hook: ```js +import * as React from 'react'; +import { ScrollView } from 'react-native'; +import { useScrollToTop } from '@react-navigation/native'; + class Albums extends React.Component { render() { return {/* content */}; diff --git a/versioned_docs/version-8.x/use-theme.md b/versioned_docs/version-8.x/use-theme.md index fed51e5efa0..7b28291b2b7 100644 --- a/versioned_docs/version-8.x/use-theme.md +++ b/versioned_docs/version-8.x/use-theme.md @@ -77,7 +77,7 @@ function HomeScreen() { ); } @@ -201,7 +200,10 @@ The `useDrawerProgress` hook returns a Reanimated `SharedValue` which represents Example with modern implementation: ```js -import { Animated } from 'react-native-reanimated'; +import Animated, { + interpolate, + useAnimatedStyle, +} from 'react-native-reanimated'; import { useDrawerProgress } from 'react-native-drawer-layout'; // ... @@ -213,7 +215,7 @@ function MyComponent() { return { transform: [ { - translateX: interpolate(progress, [0, 1], [-100, 0]), + translateX: interpolate(progress.value, [0, 1], [-100, 0]), }, ], }; diff --git a/versioned_docs/version-7.x/drawer-navigator.md b/versioned_docs/version-7.x/drawer-navigator.md index f17b23a4a2c..7c2849c7a50 100644 --- a/versioned_docs/version-7.x/drawer-navigator.md +++ b/versioned_docs/version-7.x/drawer-navigator.md @@ -417,7 +417,7 @@ Type of the drawer. It determines how the drawer looks and animates. Defaults to `slide` on iOS and `front` on other platforms. -You can conditionally specify the `drawerType` to show a permanent drawer on bigger screens and a traditional drawer drawer on small screens: +You can conditionally specify the `drawerType` to show a permanent drawer on bigger screens and a traditional drawer on small screens: ```js import { useWindowDimensions } from 'react-native'; diff --git a/versioned_docs/version-7.x/elements.md b/versioned_docs/version-7.x/elements.md index 688f45b88b4..7d7a6848803 100644 --- a/versioned_docs/version-7.x/elements.md +++ b/versioned_docs/version-7.x/elements.md @@ -251,14 +251,17 @@ const RootStack = createNativeStackNavigator({ screen: HomeScreen, options: { headerLeft: (props) => ( - { - // Do something - }}> - ) - } - } - } -}) + { + // Do something + }} + /> + ), + }, + }, + }, +}); ``` @@ -303,15 +306,18 @@ const RootStack = createNativeStackNavigator({ Home: { screen: HomeScreen, options: { - headerLeft: (props) => ( - { - // Do something - }}> - ) - } - } - } -}) + headerRight: (props) => ( + { + // Do something + }} + /> + ), + }, + }, + }, +}); ``` @@ -322,7 +328,7 @@ const RootStack = createNativeStackNavigator({ name="Home" component={HomeScreen} options={{ - headerLeft: (props) => ( + headerRight: (props) => ( { @@ -744,7 +750,7 @@ Usage: ### `SafeAreaProviderCompat` -A wrapper over the `SafeAreaProvider` component from [`react-native-safe-area-context](https://github.com/th3rdwave/react-native-safe-area-context) which includes initial values. +A wrapper over the `SafeAreaProvider` component from [`react-native-safe-area-context`](https://github.com/th3rdwave/react-native-safe-area-context) which includes initial values. Usage: diff --git a/versioned_docs/version-7.x/group.md b/versioned_docs/version-7.x/group.md index 4a7b6583abb..03d6041b026 100644 --- a/versioned_docs/version-7.x/group.md +++ b/versioned_docs/version-7.x/group.md @@ -68,7 +68,7 @@ const MyStack = createNativeStackNavigator({ }); // codeblock-focus-end -const Navigation = createStaticNavigation(Stack); +const Navigation = createStaticNavigation(MyStack); export default function App() { return ; diff --git a/versioned_docs/version-7.x/handling-safe-area.md b/versioned_docs/version-7.x/handling-safe-area.md index b632c672d8f..6f43a24f8c5 100755 --- a/versioned_docs/version-7.x/handling-safe-area.md +++ b/versioned_docs/version-7.x/handling-safe-area.md @@ -407,7 +407,7 @@ import * as React from 'react'; import { Text, View } from 'react-native'; import { NavigationContainer } from '@react-navigation/native'; import { createBottomTabNavigator } from '@react-navigation/bottom-tabs'; -import { createStackNavigator } from '@react-navigation/stack'; +import { createNativeStackNavigator } from '@react-navigation/native-stack'; // codeblock-focus-start import { SafeAreaProvider, @@ -434,7 +434,7 @@ function Demo() { } // codeblock-focus-end -const Stack = createStackNavigator(); +const Stack = createNativeStackNavigator(); const Tab = createBottomTabNavigator(); export default function App() { diff --git a/versioned_docs/version-7.x/headers.md b/versioned_docs/version-7.x/headers.md index 30575084bbf..ec5e03f6d74 100755 --- a/versioned_docs/version-7.x/headers.md +++ b/versioned_docs/version-7.x/headers.md @@ -314,7 +314,7 @@ All screens in this navigator will now share these styles. Individual screens ca ## Replacing the title with a custom component -Sometimes you need more control than changing the text and styles of your title -- for example, you may want to render an image in place of the title, or make the title into a button. In these cases, you can completely override the component used for the title and provide your own. +Sometimes you need more control than changing the text and styles of your title - for example, you may want to render an image in place of the title, or make the title into a button. In these cases, you can completely override the component used for the title and provide your own. ```js name="Custom title" snack static2dynamic import * as React from 'react'; diff --git a/versioned_docs/version-7.x/hello-react-navigation.md b/versioned_docs/version-7.x/hello-react-navigation.md index fc4c5027bc5..ad1bd082512 100755 --- a/versioned_docs/version-7.x/hello-react-navigation.md +++ b/versioned_docs/version-7.x/hello-react-navigation.md @@ -138,7 +138,7 @@ If you run this code, you will see a screen with an empty navigation bar and a g :::tip -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 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. ::: diff --git a/versioned_docs/version-7.x/material-top-tab-navigator.md b/versioned_docs/version-7.x/material-top-tab-navigator.md index 421f084ecec..ea2b95482a8 100755 --- a/versioned_docs/version-7.x/material-top-tab-navigator.md +++ b/versioned_docs/version-7.x/material-top-tab-navigator.md @@ -151,7 +151,7 @@ String indicating whether the keyboard gets dismissed in response to a drag gest - `'on-drag'`: the keyboard is dismissed when a drag begins. - `'none'`: drags do not dismiss the keyboard. -##### `overScrollMode` +#### `overScrollMode` Used to override default value of pager's overScroll mode. @@ -169,7 +169,7 @@ Object containing the initial height and width of the screens. Passing this will ```js { - width: Dimensions.get('window').width; + width: Dimensions.get('window').width, } ``` diff --git a/versioned_docs/version-7.x/modal.md b/versioned_docs/version-7.x/modal.md index b97ab63ad42..2596b7257fc 100755 --- a/versioned_docs/version-7.x/modal.md +++ b/versioned_docs/version-7.x/modal.md @@ -108,9 +108,9 @@ export default function App() { -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. +Here, we are creating 2 groups of screens. 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), `modal`, or `transparentModal`. 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`. +Instead of specifying this option for a group, it's also possible to specify it for a single screen using the `options` property. ## Summary diff --git a/versioned_docs/version-7.x/more-resources.md b/versioned_docs/version-7.x/more-resources.md index 8e71db8cf3a..a3969e235db 100755 --- a/versioned_docs/version-7.x/more-resources.md +++ b/versioned_docs/version-7.x/more-resources.md @@ -6,6 +6,8 @@ sidebar_label: More resources ## Talks +These are historical talks from earlier React Navigation versions. + - [Mobile App Development with React Native at Harvard Extension School](https://cs50.harvard.edu/mobile/2018/): Lecture 6 covers React Navigation, includes exercises, slides, and video. - [Mobile Navigation at React Alicante](https://www.youtube.com/watch?v=GBhdooVxX6Q): An overview and comparison of the approaches taken by react-native-navigation and react-navigation. diff --git a/versioned_docs/version-7.x/multiple-drawers.md b/versioned_docs/version-7.x/multiple-drawers.md index 7b01d1d4a50..acf0752b481 100644 --- a/versioned_docs/version-7.x/multiple-drawers.md +++ b/versioned_docs/version-7.x/multiple-drawers.md @@ -202,11 +202,13 @@ export default function App() { 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-object.md#getparent) to refer to the right drawer which is the parent of the left drawer. So our code would look like: +To solve this, we need to use [`navigation.getParent`](navigation-object.md#getparent) to refer to the right drawer, which is the parent of the left drawer. So our code would look like: ```js - - + + ``` However, this means that our button needs to know about the parent navigators, which isn't ideal. If our button is further nested inside other navigators, it'd need multiple `getParent()` calls. To address this, we can use the [`id` prop](navigator.md#id) to identify the parent navigator. diff --git a/versioned_docs/version-7.x/native-stack-navigator.md b/versioned_docs/version-7.x/native-stack-navigator.md index d48446db908..03f29f86dc1 100755 --- a/versioned_docs/version-7.x/native-stack-navigator.md +++ b/versioned_docs/version-7.x/native-stack-navigator.md @@ -136,7 +136,7 @@ Supported values: - `"none"` - `"slide"` -On Android, setting either `fade` or `slide` will set the transition of status bar color. On iOS, this option applies to the appereance animation of the status bar. +On Android, setting either `fade` or `slide` will set the transition of status bar color. On iOS, this option applies to the appearance animation of the status bar. Requires setting `View controller-based status bar appearance -> YES` (or removing the config) in your `Info.plist` file. @@ -1361,9 +1361,9 @@ The native stack navigator exports the following hooks: #### `useAnimatedHeaderHeight` -The hook returns an animated value representing the height of the header. This is similar to [`useHeaderHeight`](elements.md#useheaderheight) but returns an animated value that changed as the header height changes, e.g. when expanding or collapsing large title or search bar on iOS. +The hook returns an animated value representing the height of the header. This is similar to [`useHeaderHeight`](elements.md#useheaderheight) but returns an animated value that changes as the header height changes, e.g. when expanding or collapsing large title or search bar on iOS. -It can be used to animated content along with header height changes. +It can be used to animate content along with header height changes. ```js import { Animated } from 'react-native'; diff --git a/versioned_docs/version-7.x/navigating-without-navigation-prop.md b/versioned_docs/version-7.x/navigating-without-navigation-prop.md index 0200c83209a..4c130707c5f 100755 --- a/versioned_docs/version-7.x/navigating-without-navigation-prop.md +++ b/versioned_docs/version-7.x/navigating-without-navigation-prop.md @@ -7,7 +7,7 @@ sidebar_label: Navigation Ref import Tabs from '@theme/Tabs'; import TabItem from '@theme/TabItem'; -Sometimes you need to trigger a navigation action from places where you do not have access to the `navigation` object, such as a Redux middleware. For such cases, you can dispatch navigation actions use a [`ref` on the navigation container](navigation-container.md#ref). +Sometimes you need to trigger a navigation action from places where you do not have access to the `navigation` object, such as a Redux middleware. For such cases, you can dispatch navigation actions using a [`ref` on the navigation container](navigation-container.md#ref). **Do not** use the `ref` if: @@ -76,7 +76,7 @@ export function navigate(name, params) { // add other navigation functions that you need and export them ``` -Then, in any of your javascript modules, import the `RootNavigation` and call functions which you exported from it. You may use this approach outside of your React components and, in fact, it works as well when used from within them. +Then, in any of your javascript modules, import the `RootNavigation` and call functions which you exported from it. You may use this approach outside of your React components. @@ -227,7 +227,7 @@ When writing tests, you may mock the navigation functions, and make assertions o ## Handling initialization -When using this pattern, you need to keep few things in mind to avoid navigation from failing in your app. +When using this pattern, you need to keep a few things in mind to avoid navigation from failing in your app. - The `ref` is set only after the navigation container renders, this can be async when handling deep links - A navigator needs to be rendered to be able to handle actions, the `ref` won't be ready without a navigator @@ -356,4 +356,4 @@ export default function App() { -If you're unsure if a navigator is rendered, you can call `navigationRef.current.getRootState()`, and it'll return a valid state object if any navigators are rendered, otherwise it will return `undefined`. +If you're unsure if a navigator is rendered, you can call `navigationRef.getRootState()`, and it'll return a valid state object if any navigators are rendered, otherwise it will return `undefined`. diff --git a/versioned_docs/version-7.x/navigation-actions.md b/versioned_docs/version-7.x/navigation-actions.md index a4480e69e77..6dbac554764 100755 --- a/versioned_docs/version-7.x/navigation-actions.md +++ b/versioned_docs/version-7.x/navigation-actions.md @@ -12,7 +12,7 @@ A navigation action is an object containing at least a `type` property. Internal Each navigation actions can contain at least the following properties: - `type` (required) - A string that represents the name of the action. -- `payload` (options) - An object containing additional information about the action. For example, it will contain `name` and `params` for `navigate`. +- `payload` (optional) - An object containing additional information about the action. For example, it will contain `name` and `params` for `navigate`. - `source` (optional) - The key of the route which should be considered as the source of the action. This is used for some actions to determine which route to apply the action on. By default, `navigation.dispatch` adds the key of the route that dispatched the action. - `target` (optional) - The key of the [navigation state](navigation-state.md) the action should be applied on. @@ -111,7 +111,7 @@ In a stack navigator ([stack](stack-navigator.md) or [native stack](native-stack
Advanced usage -The `navigate` action can also accepts an object as the argument with the following properties: +The `navigate` action can also accept an object as the argument with the following properties: - `name` - _string_ - A destination name of the screen in the current or a parent navigator - `params` - _object_ - Params to use for the destination route. @@ -188,7 +188,7 @@ function ProfileScreen({ route }) { routes: [ { name: 'Profile', - params: { user: 'jane', key: route.params.key }, + params: { user: 'jane' }, }, { name: 'Home' }, ], @@ -555,7 +555,7 @@ if (navigation.isFocused()) { ### setParams -The `setParams` action allows to replace params for a certain route. It takes the following arguments: +The `setParams` action allows to merge params for a certain route. It takes the following arguments: - `params` - _object_ - required - New params to be merged into existing route params. diff --git a/versioned_docs/version-7.x/navigation-container.md b/versioned_docs/version-7.x/navigation-container.md index 536dd908ae2..80cebf276df 100644 --- a/versioned_docs/version-7.x/navigation-container.md +++ b/versioned_docs/version-7.x/navigation-container.md @@ -81,10 +81,14 @@ import { // codeblock-focus-end import { createStackNavigator } from '@react-navigation/stack'; +function EmptyScreen() { + return ; +} + const Stack = createStackNavigator({ initialRouteName: 'Empty', screens: { - Empty: () => , + Empty: EmptyScreen, Home: HomeScreen, }, }); @@ -140,6 +144,10 @@ function HomeScreen() { ); } +function EmptyScreen() { + return ; +} + // codeblock-focus-start export default function App() { @@ -151,7 +159,7 @@ export default function App() { - } /> + @@ -537,7 +545,7 @@ Example: ```js ```js -const Tab = createBottomTabNavigatior({ +const Tab = createBottomTabNavigator({ screens: { Chat: { screen: Chat, @@ -338,7 +338,7 @@ Example: ```js -const Tab = createBottomTabNavigatior({ +const Tab = createBottomTabNavigator({ screens: { Chat: { screen: Chat, @@ -436,7 +436,7 @@ Similar to `listeners`, you can also pass a function to `screenListeners`. The f ```js -const Tab = createBottomTabNavigatior({ +const Tab = createBottomTabNavigator({ screenListeners: ({ navigation }) => ({ state: (e) => { // Do something with the state diff --git a/versioned_docs/version-7.x/navigation-lifecycle.md b/versioned_docs/version-7.x/navigation-lifecycle.md index cd05bbe3791..970f2636266 100755 --- a/versioned_docs/version-7.x/navigation-lifecycle.md +++ b/versioned_docs/version-7.x/navigation-lifecycle.md @@ -488,7 +488,7 @@ export default function App() { See [Navigation events](navigation-events.md) for more details. -For performing side effects, we can use the [`useFocusEffect`](use-focus-effect.md) - it's like `useEffect` but ties to the navigation lifecycle -- it runs the effect when the screen comes into focus and cleans it up when the screen goes out of focus: +For performing side effects, we can use the [`useFocusEffect`](use-focus-effect.md) - it's like `useEffect` but ties to the navigation lifecycle - it runs the effect when the screen comes into focus and cleans it up when the screen goes out of focus: diff --git a/versioned_docs/version-7.x/navigation-object.md b/versioned_docs/version-7.x/navigation-object.md index 57514d248a6..652d262108e 100755 --- a/versioned_docs/version-7.x/navigation-object.md +++ b/versioned_docs/version-7.x/navigation-object.md @@ -219,7 +219,7 @@ function ProfileScreen({ route }) { {route.params.names[0]} {route.params.names[1]} {route.params.names[2]} - + ); } @@ -481,7 +481,7 @@ function HomeScreen() { }); }} > - Go to Brents profile + Go to Brent's profile ); @@ -531,7 +531,7 @@ function ProfileScreen({ route }) { > Reset navigator state to Settings - + ); @@ -617,7 +617,7 @@ function HomeScreen() { }); }} > - Go to Brents profile + Go to Brent's profile ); @@ -667,12 +667,11 @@ function ProfileScreen({ route }) { > Reset navigator state to Settings - + ); @@ -700,7 +699,7 @@ function SettingsScreen({ route }) { }); }} > - Go to Brents profile + Go to Brent's profile ); @@ -1003,7 +1002,7 @@ function HomeScreen() { }); }} > - Go to Brents profile + Go to Brent's profile ); @@ -1102,7 +1101,7 @@ function HomeScreen() { }); }} > - Go to Brents profile + Go to Brent's profile ); @@ -1211,7 +1210,7 @@ function HomeScreen() { }); }} > - Go to Brents profile + Go to Brent's profile ); @@ -1310,7 +1309,7 @@ function HomeScreen() { }); }} > - Go to Brents profile + Go to Brent's profile ); @@ -1745,7 +1744,7 @@ This method lets us check whether the screen is currently focused. Returns `true const isFocused = navigation.isFocused(); ``` -This method doesn't re-render the screen when the value changes and mainly useful in callbacks. You probably want to use [useIsFocused](use-is-focused.md) instead of using this directly, it will return a boolean a prop to indicating if the screen is focused. +This method doesn't re-render the screen when the value changes and is mainly useful in callbacks. You probably want to use [useIsFocused](use-is-focused.md) instead of using this directly, as the hook re-renders the screen when focus changes. ## Advanced API Reference @@ -1782,8 +1781,8 @@ import { CommonActions } from '@react-navigation/native'; navigation.dispatch({ ...CommonActions.navigate('Profile'), - source: 'someRoutekey', - target: 'someStatekey', + source: 'someRouteKey', + target: 'someStateKey', }); ``` diff --git a/versioned_docs/version-7.x/nesting-navigators.md b/versioned_docs/version-7.x/nesting-navigators.md index 51b96a2a767..e0fd9119700 100755 --- a/versioned_docs/version-7.x/nesting-navigators.md +++ b/versioned_docs/version-7.x/nesting-navigators.md @@ -960,7 +960,7 @@ const HomeTabs = createBottomTabNavigator({ }, }); -const RootStack = createStackNavigator({ +const RootStack = createNativeStackNavigator({ // highlight-start screenOptions: { headerShown: false, @@ -1025,7 +1025,7 @@ Think of nesting as a way to achieve the UI you want, not a way to organize your ```js -const MyStack = createStackNavigator({ +const MyStack = createNativeStackNavigator({ screens: { // Common screens }, diff --git a/versioned_docs/version-7.x/route-object.md b/versioned_docs/version-7.x/route-object.md index 346af1b4ed1..246ad06f908 100755 --- a/versioned_docs/version-7.x/route-object.md +++ b/versioned_docs/version-7.x/route-object.md @@ -7,13 +7,13 @@ sidebar_label: Route object import Tabs from '@theme/Tabs'; import TabItem from '@theme/TabItem'; -Each `screen` component in your app is provided with the `route` object as a prop automatically. The prop contains various information regarding current route (place in navigation hierarchy component lives). +Each `screen` component in your app is provided with the `route` object as a prop automatically. The prop contains information about the current route. - `route` - `key` - Unique key of the screen. Created automatically or added while navigating to this screen. - `name` - Name of the screen. Defined in navigator component hierarchy. - - `path` - An optional string containing the path that opened the screen, exists when the screen was opened via a deep link. - - `params` - An optional object containing params which is defined while navigating e.g. `navigate('Twitter', { user: 'Dan Abramov' })`. + - `path` - An optional string containing the path that opened the screen. It exists when the screen was opened via a deep link. + - `params` - An optional object containing params defined while navigating, e.g. `navigate('Twitter', { user: 'Jane Doe' })`. @@ -26,7 +26,10 @@ import { createNativeStackNavigator } from '@react-navigation/native-stack'; const Stack = createNativeStackNavigator({ screens: { - Profile: ProfileScreen, + Profile: { + screen: ProfileScreen, + initialParams: { user: 'Jane Doe' }, + }, }, }); @@ -36,6 +39,8 @@ function ProfileScreen({ route }) { This is the profile screen of the app {route.name} + {route.path ?? 'No path'} + {route.params?.user ?? 'No params'} ); } @@ -65,6 +70,8 @@ function ProfileScreen({ route }) { This is the profile screen of the app {route.name} + {route.path ?? 'No path'} + {route.params?.user ?? 'No params'} ); } @@ -74,7 +81,11 @@ export default function App() { return ( - + ); diff --git a/versioned_docs/version-7.x/screen-options-resolution.md b/versioned_docs/version-7.x/screen-options-resolution.md index 1a97af4543a..857bca1e875 100755 --- a/versioned_docs/version-7.x/screen-options-resolution.md +++ b/versioned_docs/version-7.x/screen-options-resolution.md @@ -31,7 +31,7 @@ function B() { return ; } -// codeblock-focus-start +// codeblock-focus-end const HomeStackScreen = createNativeStackNavigator({ screens: { A: { diff --git a/versioned_docs/version-7.x/screen-options.md b/versioned_docs/version-7.x/screen-options.md index 283e37bcf3b..b81d4f8d780 100644 --- a/versioned_docs/version-7.x/screen-options.md +++ b/versioned_docs/version-7.x/screen-options.md @@ -88,9 +88,9 @@ const RootStack = createNativeStackNavigator({ screen: HomeScreen, options: ({ navigation }) => ({ title: 'Awesome app', - headerLeft: () => { - navigation.toggleDrawer()} />; - }, + headerLeft: () => ( + + ), }), }, }, @@ -238,10 +238,12 @@ const Stack = createNativeStackNavigator({ }, groups: { Modal: { - screenOptions: { + screenOptions: ({ navigation }) => ({ presentation: 'modal', - headerLeft: () => , - }, + headerLeft: () => ( + + ), + }), screens: { Settings: Settings, Share: Share, @@ -261,7 +263,9 @@ const Stack = createNativeStackNavigator({ ({ presentation: 'modal', - headerLeft: () => , + headerLeft: () => ( + + ), })} > diff --git a/versioned_docs/version-7.x/screen-tracking.md b/versioned_docs/version-7.x/screen-tracking.md index a77407c9233..90eb0e4871e 100644 --- a/versioned_docs/version-7.x/screen-tracking.md +++ b/versioned_docs/version-7.x/screen-tracking.md @@ -74,15 +74,15 @@ export default function App() { return ( { + onReady={async () => { routeNameRef.current = navigationRef.current.getCurrentRoute().name; + + // Replace the line below to add the tracker from a mobile analytics SDK + await trackScreenView(routeNameRef.current); }} onStateChange={async () => { const previousRouteName = routeNameRef.current; const currentRouteName = navigationRef.current.getCurrentRoute().name; - const trackScreenView = () => { - // Your implementation of analytics goes here! - }; if (previousRouteName !== currentRouteName) { // Replace the line below to add the tracker from a mobile analytics SDK @@ -147,7 +147,7 @@ export default function App() { return ( { + onReady={async () => { routeNameRef.current = navigationRef.current.getCurrentRoute().name; // Replace the line below to add the tracker from a mobile analytics SDK @@ -156,9 +156,6 @@ export default function App() { onStateChange={async () => { const previousRouteName = routeNameRef.current; const currentRouteName = navigationRef.current.getCurrentRoute().name; - const trackScreenView = () => { - // Your implementation of analytics goes here! - }; if (previousRouteName !== currentRouteName) { // Replace the line below to add the tracker from a mobile analytics SDK diff --git a/versioned_docs/version-7.x/server-container.md b/versioned_docs/version-7.x/server-container.md index 655b158feac..ac22ef72181 100644 --- a/versioned_docs/version-7.x/server-container.md +++ b/versioned_docs/version-7.x/server-container.md @@ -12,8 +12,8 @@ Example: // Ref which will be populated with the screen options const ref = React.createRef(); -// Location object containing the `pathname` and `search` fields of the current URL -const location = { pathname: '/profile', search: '?user=jane' }; +// Location object - can be a URL object or an object with `pathname` and `search` fields +const location = new URL('/profile?user=jane', 'https://example.org/'); // Get rendered HTML const html = ReactDOMServer.renderToString( @@ -23,10 +23,10 @@ const html = ReactDOMServer.renderToString( ); // Then you can access the options for the current screen in the ref -const options = ref.current.getCurrentOptions(); // { title: 'My Profile' } +const options = ref.current?.getCurrentOptions(); // { title: 'My Profile' } ``` -The `ServerContainer` component should wrap your entire app during server rendering. Note that you still need a `NavigationContainer` in your app, `ServerContainer` doesn't replace it.' +The `ServerContainer` component should wrap your entire app during server rendering. Note that you still need a `NavigationContainer` in your app, `ServerContainer` doesn't replace it. See the [`server rendering guide`](server-rendering.md) for a detailed guide and examples. diff --git a/versioned_docs/version-7.x/server-rendering.md b/versioned_docs/version-7.x/server-rendering.md index 0850ff1404e..6efc221b868 100644 --- a/versioned_docs/version-7.x/server-rendering.md +++ b/versioned_docs/version-7.x/server-rendering.md @@ -61,7 +61,7 @@ Here, `./src/App` is the file where you have `AppRegistry.registerComponent('App If you're using React Navigation in your app, this will render the screens rendered by your home page. However, if you have [configured links](configuring-links.md) in your app, you'd want to render the correct screens for the request URL on server so that it matches what'll be rendered on the client. -We can use the [`ServerContainer`](server-container.md) to do that by passing this info in the `location` prop. For example, with Koa, you can use the `path` and `search` properties from the context argument: +We can use the [`ServerContainer`](server-container.md) to do that by passing this info in the `location` prop. For example, with Koa, you can create a `URL` object from `ctx.url`: ```js app.use(async (ctx) => { @@ -103,13 +103,10 @@ app.use(async (ctx) => { const { element, getStyleElement } = AppRegistry.getApplication('App'); - const ref = React.createRef(); + const ref = React.createRef(); const html = ReactDOMServer.renderToString( - + {element} ); @@ -128,7 +125,7 @@ app.use(async (ctx) => { content="width=device-width, initial-scale=1, minimum-scale=1, maximum-scale=1.00001, viewport-fit=cover" > ${css} - ${options.title} + ${options?.title ?? 'My App'}
${html} @@ -252,5 +249,5 @@ You can follow a similar approach for other status codes too, for example, `401` ## Summary - Use the `location` prop on `ServerContainer` to render correct screens based on the incoming request. -- Attach a `ref` to the `ServerContainer` get options for the current screen. +- Attach a `ref` to the `ServerContainer` to get options for the current screen. - Use context to attach more information such as status code. diff --git a/versioned_docs/version-7.x/stack-actions.md b/versioned_docs/version-7.x/stack-actions.md index 1f8ae3bcc23..20b239b3ace 100755 --- a/versioned_docs/version-7.x/stack-actions.md +++ b/versioned_docs/version-7.x/stack-actions.md @@ -387,7 +387,7 @@ export default function App() { ## popToTop -The `popToTop` action takes you back to the first screen in the stack, dismissing all the others. It's functionally identical to `StackActions.pop({n: currentIndex})`. +The `popToTop` action takes you back to the first screen in the stack, dismissing all the others. ```js name="Stack actions popToTop" snack static2dynamic import * as React from 'react'; diff --git a/versioned_docs/version-7.x/stack-navigator.md b/versioned_docs/version-7.x/stack-navigator.md index 18413c147c8..37ff7b0287a 100755 --- a/versioned_docs/version-7.x/stack-navigator.md +++ b/versioned_docs/version-7.x/stack-navigator.md @@ -625,6 +625,7 @@ Stack Navigator exposes various options to configure the transition animation wh useNavigation, } from '@react-navigation/native'; import { Button } from '@react-navigation/elements'; + import { Animated } from 'react-native'; import { createStackNavigator } from '@react-navigation/stack'; function HomeScreen() { @@ -725,6 +726,7 @@ Stack Navigator exposes various options to configure the transition animation wh useNavigation, } from '@react-navigation/native'; import { Button } from '@react-navigation/elements'; + import { Animated } from 'react-native'; import { createStackNavigator } from '@react-navigation/stack'; function HomeScreen() { @@ -853,7 +855,7 @@ const forSlide = ({ current, next, inverted, layouts: { screen } }) => { - `titleStyle` - Style for the header title text. - `backgroundStyle` - Style for the header background. - The function receives the following properties in it's argument: + The function receives the following properties in its argument: - `current` - Values for the current screen (the screen which owns this header). - `progress` - Animated node representing the progress value of the current screen. `0` when screen should start coming into view, `0.5` when it's mid-way, `1` when it should be fully in view. - `next` - Values for the screen after this one in the stack. This can be `undefined` in case the screen animating is the last one. @@ -894,6 +896,7 @@ const forSlide = ({ current, next, inverted, layouts: { screen } }) => { useNavigation, } from '@react-navigation/native'; import { Button } from '@react-navigation/elements'; + import { Animated } from 'react-native'; import { createStackNavigator } from '@react-navigation/stack'; function HomeScreen() { diff --git a/versioned_docs/version-7.x/static-configuration.md b/versioned_docs/version-7.x/static-configuration.md index a272bef5a71..cbe4f8fea13 100644 --- a/versioned_docs/version-7.x/static-configuration.md +++ b/versioned_docs/version-7.x/static-configuration.md @@ -84,7 +84,7 @@ The `screens` object can contain key value pairs where the key is the name of th The `groups` object can contain key-value pairs where the key is the name of the group and the value is the group configuration. -The configuration object for a screen accepts the [properties described in the Group page](group.md). In addition, the following properties are available when using static configuration: +The configuration object for a group accepts the [properties described in the Group page](group.md). In addition, the following properties are available when using static configuration: - `if` - this can be used to conditionally render the group and works the same as the [`if` property in the screen configuration](#if). - `screens` - an object containing configuration for each screen in the group. The configuration is the same as the [`screens` object in the navigator configuration](#screens). diff --git a/versioned_docs/version-7.x/static-vs-dynamic.md b/versioned_docs/version-7.x/static-vs-dynamic.md index 5ee357e20cc..762b65f6b95 100644 --- a/versioned_docs/version-7.x/static-vs-dynamic.md +++ b/versioned_docs/version-7.x/static-vs-dynamic.md @@ -366,7 +366,7 @@ With both approaches, you can access the route params of the parent screen with ## Deep linking -For deep links and dynamic links, the dynamic API requires a linking configuration that maps navigation structure to path patterns. In the static API, the paths can be generated based on the screen name and automatically by specifying `enabled: 'auto'`. Custom path patterns can be defined on each screen's `linking` property: +For deep links and dynamic links, the dynamic API requires a linking configuration that maps navigation structure to path patterns. In the static API, the paths can be generated automatically based on the screen name by specifying `enabled: 'auto'`. Custom path patterns can be defined on each screen's `linking` property: ```js title="Dynamic API" const linking = { diff --git a/versioned_docs/version-7.x/status-bar.md b/versioned_docs/version-7.x/status-bar.md index 9b97b4820db..9f9bcf3263c 100755 --- a/versioned_docs/version-7.x/status-bar.md +++ b/versioned_docs/version-7.x/status-bar.md @@ -114,10 +114,7 @@ import { View, Text, StatusBar, StyleSheet } from 'react-native'; import { NavigationContainer, useNavigation } from '@react-navigation/native'; import { createNativeStackNavigator } from '@react-navigation/native-stack'; import { Button } from '@react-navigation/elements'; -import { - SafeAreaProvider, - useSafeAreaInsets, -} from 'react-native-safe-area-context'; +import { useSafeAreaInsets } from 'react-native-safe-area-context'; function Screen1() { const navigation = useNavigation(); @@ -179,14 +176,12 @@ const Stack = createNativeStackNavigator(); export default function App() { return ( - - - - - - - - + + + + + + ); } @@ -340,10 +335,7 @@ import { useIsFocused } from '@react-navigation/native'; import { NavigationContainer, useNavigation } from '@react-navigation/native'; import { createNativeStackNavigator } from '@react-navigation/native-stack'; import { Button } from '@react-navigation/elements'; -import { - SafeAreaProvider, - useSafeAreaInsets, -} from 'react-native-safe-area-context'; +import { useSafeAreaInsets } from 'react-native-safe-area-context'; function FocusAwareStatusBar(props) { const isFocused = useIsFocused(); @@ -409,14 +401,12 @@ const Stack = createNativeStackNavigator(); export default function App() { return ( - - - - - - - - + + + + + + ); } diff --git a/versioned_docs/version-7.x/tab-view.md b/versioned_docs/version-7.x/tab-view.md index ecb3cb1899b..9c7f25ba147 100644 --- a/versioned_docs/version-7.x/tab-view.md +++ b/versioned_docs/version-7.x/tab-view.md @@ -222,7 +222,7 @@ If you need to pass additional props, use a custom `renderScene` function: const renderScene = ({ route }) => { switch (route.key) { case 'first': - return ; + return ; case 'second': return ; default: @@ -316,7 +316,7 @@ Only supported on Android. Boolean indicating whether to enable swipe gestures. Swipe gestures are enabled by default. Passing `false` will disable swipe gestures, but the user can still switch tabs by pressing the tab bar. -#### `animationEnabled` +##### `animationEnabled` Enables animation when changing tab. By default it's true. diff --git a/versioned_docs/version-7.x/testing.md b/versioned_docs/version-7.x/testing.md index a39c33b1fdb..e25b36e32d2 100644 --- a/versioned_docs/version-7.x/testing.md +++ b/versioned_docs/version-7.x/testing.md @@ -333,12 +333,12 @@ const SurpriseScreen = () => { const [textVisible, setTextVisible] = useState(false); useEffect(() => { - navigation.addListener('transitionEnd', () => setTextVisible(true)); + return navigation.addListener('transitionEnd', () => setTextVisible(true)); }, [navigation]); return ( - {textVisible ? Surprise! : ''} + {textVisible ? Surprise! : null} ); }; @@ -380,12 +380,12 @@ const SurpriseScreen = () => { const [textVisible, setTextVisible] = useState(false); useEffect(() => { - navigation.addListener('transitionEnd', () => setTextVisible(true)); + return navigation.addListener('transitionEnd', () => setTextVisible(true)); }, [navigation]); return ( - {textVisible ? Surprise! : ''} + {textVisible ? Surprise! : null} ); }; @@ -638,7 +638,7 @@ export function MyTabs() { return ( - + ); } @@ -699,9 +699,9 @@ test('loads data on Pokemon info screen after focus', async () => { render(); const homeTabButton = screen.getByLabelText('Home, tab, 1 of 2'); - const profileTabButton = screen.getByLabelText('Profile, tab, 2 of 2'); + const pokemonTabButton = screen.getByLabelText('Pokemon, tab, 2 of 2'); - await user.press(profileTabButton); + await user.press(pokemonTabButton); expect(screen.getByText('Loading...')).toBeVisible(); @@ -713,7 +713,7 @@ test('loads data on Pokemon info screen after focus', async () => { await act(() => jest.runAllTimers()); - await user.press(profileTabButton); + await user.press(pokemonTabButton); expect(screen.queryByText('Loading...')).not.toBeVisible(); expect(screen.getByText('ditto')).toBeVisible(); @@ -744,9 +744,9 @@ test('loads data on Pokemon info screen after focus', async () => { ); const homeTabButton = screen.getByLabelText('Home, tab, 1 of 2'); - const profileTabButton = screen.getByLabelText('Profile, tab, 2 of 2'); + const pokemonTabButton = screen.getByLabelText('Pokemon, tab, 2 of 2'); - await user.press(profileTabButton); + await user.press(pokemonTabButton); expect(screen.getByText('Loading...')).toBeVisible(); @@ -758,7 +758,7 @@ test('loads data on Pokemon info screen after focus', async () => { await act(() => jest.runAllTimers()); - await user.press(profileTabButton); + await user.press(pokemonTabButton); expect(screen.queryByText('Loading...')).not.toBeVisible(); expect(screen.getByText('ditto')).toBeVisible(); @@ -789,7 +789,12 @@ In a production app, we recommend using a library like [React Query](https://tan To make it easier to test components that don't depend on the navigation structure, we can create a light-weight test navigator: ```js title="TestStackNavigator.js" -import { useNavigationBuilder, StackRouter } from '@react-navigation/native'; +import { + createNavigatorFactory, + useNavigationBuilder, + StackRouter, +} from '@react-navigation/native'; +import { View } from 'react-native'; function TestStackNavigator(props) { const { state, descriptors, NavigationContent } = useNavigationBuilder( diff --git a/versioned_docs/version-7.x/themes.md b/versioned_docs/version-7.x/themes.md index b404eda2d95..d89aca22b7c 100755 --- a/versioned_docs/version-7.x/themes.md +++ b/versioned_docs/version-7.x/themes.md @@ -106,6 +106,8 @@ When creating a custom theme, you will need to provide all of these properties. Example theme ```js +import { Platform } from 'react-native'; + const WEB_FONT_STACK = 'system-ui, "Segoe UI", Roboto, Helvetica, Arial, sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol"'; diff --git a/versioned_docs/version-7.x/troubleshooting.md b/versioned_docs/version-7.x/troubleshooting.md index 1186ea690eb..7479635e647 100755 --- a/versioned_docs/version-7.x/troubleshooting.md +++ b/versioned_docs/version-7.x/troubleshooting.md @@ -39,7 +39,7 @@ rm -rf $TMPDIR/metro-bundler-cache-* ### Missing peer dependency -If the module points to an npm package (i.e. the name of the module doesn't with `./`), then it's probably due to a missing dependency. To fix this, install the dependency in your project: +If the module points to an npm package (i.e. the name of the module doesn't start with `./`), then it's probably due to a missing dependency. To fix this, install the dependency in your project: ```bash npm2yarn npm install name-of-the-module @@ -113,7 +113,7 @@ npm install --save-dev typescript ## I'm getting an error "null is not an object (evaluating 'RNGestureHandlerModule.default.Direction')" -This and some similar errors might occur if you have a bare React Native project and the library [`react-native-gesture-handler`](https://github.com/software-mansion/react-native-gesture-handler) library isn't linked. +This and some similar errors might occur if you have a bare React Native project and the library [`react-native-gesture-handler`](https://github.com/software-mansion/react-native-gesture-handler) isn't linked. Linking is automatic from React Native 0.60, so if you have linked the library manually, first unlink it: @@ -133,7 +133,7 @@ Now rebuild the app and test on your device or simulator. ## I'm getting an error "requireNativeComponent: "RNCSafeAreaProvider" was not found in the UIManager" -This and some similar errors might occur if you have a bare React Native project and the library [`react-native-safe-area-context`](https://github.com/th3rdwave/react-native-safe-area-context) library isn't linked. +This and some similar errors might occur if you have a bare React Native project and the library [`react-native-safe-area-context`](https://github.com/th3rdwave/react-native-safe-area-context) isn't linked. Linking is automatic from React Native 0.60, so if you have linked the library manually, first unlink it: @@ -301,7 +301,7 @@ const Stack = createNativeStackNavigator({ , }} @@ -338,7 +338,7 @@ const Stack = createNativeStackNavigator({ (); ``` -If you're using a regular `ref` object, you can pass a generic to the `NavigationContainerRef` type.. +If you're using a regular `ref` object, you can pass a generic to the `NavigationContainerRef` type. Example when using `React.useRef` hook: @@ -524,7 +524,7 @@ export type HomeTabParamList = { export type HomeTabScreenProps = CompositeScreenProps< BottomTabScreenProps, - RootStackScreenProps + RootStackScreenProps<'Home'> >; declare global { diff --git a/versioned_docs/version-7.x/use-focus-effect.md b/versioned_docs/version-7.x/use-focus-effect.md index 771a42aeca2..772502f5a15 100755 --- a/versioned_docs/version-7.x/use-focus-effect.md +++ b/versioned_docs/version-7.x/use-focus-effect.md @@ -54,7 +54,7 @@ export default function App() { :::warning -To avoid the running the effect too often, it's important to wrap the callback in `useCallback` before passing it to `useFocusEffect` as shown in the example. +To avoid running the effect too often, it's important to wrap the callback in `useCallback` before passing it to `useFocusEffect` as shown in the example. ::: @@ -136,7 +136,7 @@ useFocusEffect( ); ``` -The cleanup function runs whenever the effect needs to cleanup, i.e. on `blur`, unmount, dependency change etc. It's not a good place to update the state or do something that should happen on `blur`. You should use listen to the `blur` event instead: +The cleanup function runs whenever the effect needs to cleanup, i.e. on `blur`, unmount, dependency change etc. It's not a good place to update the state or do something that should happen on `blur`. You should use the `blur` event instead: ```js React.useEffect(() => { diff --git a/versioned_docs/version-7.x/use-link-builder.md b/versioned_docs/version-7.x/use-link-builder.md index dcb3da963f7..b16bd2f949d 100644 --- a/versioned_docs/version-7.x/use-link-builder.md +++ b/versioned_docs/version-7.x/use-link-builder.md @@ -22,8 +22,9 @@ import { PlatformPressable } from '@react-navigation/elements'; function DrawerContent({ state, descriptors, navigation }) { const { buildHref } = useLinkBuilder(); - return state.routes((route) => ( + return state.routes.map((route) => ( navigation.navigate(route.name, route.params)} > @@ -45,12 +46,13 @@ There are couple of important things to note: The `buildAction` method lets us parse a `href` string into an action object that can be used with [`navigation.dispatch`](navigation-object.md#dispatch) to navigate to the relevant screen. ```js -import { Link, CommonActions, useLinkBuilder } from '@react-navigation/native'; +import { useNavigation, useLinkBuilder } from '@react-navigation/native'; import { Button } from '@react-navigation/elements'; // ... function MyComponent() { + const navigation = useNavigation(); const { buildAction } = useLinkBuilder(); return ( diff --git a/versioned_docs/version-7.x/use-link-props.md b/versioned_docs/version-7.x/use-link-props.md index 9a1834fa9ce..96c26eb01c4 100644 --- a/versioned_docs/version-7.x/use-link-props.md +++ b/versioned_docs/version-7.x/use-link-props.md @@ -103,7 +103,7 @@ function Home() { action={StackActions.replace('Profile', { id: 'jane' })} href="/users/jane" > - Getting Started + Go to Jane's Profile ); } diff --git a/versioned_docs/version-7.x/use-link-to.md b/versioned_docs/version-7.x/use-link-to.md index e75da45d473..f1696088479 100644 --- a/versioned_docs/version-7.x/use-link-to.md +++ b/versioned_docs/version-7.x/use-link-to.md @@ -7,6 +7,8 @@ sidebar_label: useLinkTo The `useLinkTo` hook lets us navigate to a screen using a path instead of a screen name based on the [`linking` options](navigation-container.md#linking). It returns a function that receives the path to navigate to. ```js +import * as React from 'react'; +import { Button } from '@react-navigation/elements'; import { useLinkTo } from '@react-navigation/native'; // ... @@ -35,10 +37,20 @@ Navigating via `href` strings is not type-safe. If you want to navigate to a scr You can wrap your class component in a function component to use the hook: ```js +import * as React from 'react'; +import { Button } from '@react-navigation/elements'; +import { useLinkTo } from '@react-navigation/native'; + class Home extends React.Component { render() { // Get it from props const { linkTo } = this.props; + + return ( + + ); } } @@ -46,6 +58,6 @@ class Home extends React.Component { export default function (props) { const linkTo = useLinkTo(); - return ; + return ; } ``` diff --git a/versioned_docs/version-7.x/use-route-path.md b/versioned_docs/version-7.x/use-route-path.md index 530bc324cb7..bcadb6b6a72 100644 --- a/versioned_docs/version-7.x/use-route-path.md +++ b/versioned_docs/version-7.x/use-route-path.md @@ -13,6 +13,7 @@ The `useRoutePath` hook can be used to get the path of a route based on the [`li ```js import { useRoutePath } from '@react-navigation/native'; +import { Text } from 'react-native'; function MyComponent() { const path = useRoutePath(); diff --git a/versioned_docs/version-7.x/use-scroll-to-top.md b/versioned_docs/version-7.x/use-scroll-to-top.md index 9c714c15cbf..a6bfd392929 100755 --- a/versioned_docs/version-7.x/use-scroll-to-top.md +++ b/versioned_docs/version-7.x/use-scroll-to-top.md @@ -9,7 +9,7 @@ import TabItem from '@theme/TabItem'; The expected native behavior of scrollable components is to respond to events from navigation that will scroll to top when tapping on the active tab as you would expect from native tab bars. -In order to achieve it we export `useScrollToTop` which accept ref to scrollable component (e,g. `ScrollView` or `FlatList`). +In order to achieve it we export `useScrollToTop`, which accepts a ref to a scrollable component (e.g. `ScrollView` or `FlatList`). Example: @@ -81,6 +81,10 @@ export default function App() { You can wrap your class component in a function component to use the hook: ```js +import * as React from 'react'; +import { ScrollView } from 'react-native'; +import { useScrollToTop } from '@react-navigation/native'; + class Albums extends React.Component { render() { return {/* content */}; diff --git a/versioned_docs/version-7.x/use-theme.md b/versioned_docs/version-7.x/use-theme.md index d4b4b374f2e..3d8250ac29e 100644 --- a/versioned_docs/version-7.x/use-theme.md +++ b/versioned_docs/version-7.x/use-theme.md @@ -77,7 +77,7 @@ function HomeScreen() {