From 5d9ec025805d7a095d2dd5c76e7f4cc6468d038e Mon Sep 17 00:00:00 2001 From: Satyajit Sahoo Date: Wed, 25 Oct 2023 12:36:07 +0200 Subject: [PATCH 1/9] Rework fundamentals to accomodate static API --- static/examples/7.x/go-back.js | 10 +- static/examples/7.x/multiple-navigate.js | 10 +- static/examples/7.x/multiple-push.js | 10 +- static/examples/7.x/new-screen.js | 6 +- .../examples/7.x/params-nested-navigators.js | 14 +- static/examples/7.x/passing-params-back.js | 9 +- static/examples/7.x/passing-params.js | 10 +- static/examples/7.x/pop-to-top.js | 10 +- versioned_docs/version-7.x/getting-started.md | 24 ++- .../hello-react-navigation-static.md | 161 ++++++++++++++++++ .../version-7.x/hello-react-navigation.md | 6 +- versioned_docs/version-7.x/navigating.md | 24 ++- versioned_docs/version-7.x/params.md | 31 +++- .../version-7.x/static-configuration.md | 4 +- versioned_sidebars/version-7.x-sidebars.json | 8 +- 15 files changed, 285 insertions(+), 52 deletions(-) create mode 100644 versioned_docs/version-7.x/hello-react-navigation-static.md diff --git a/static/examples/7.x/go-back.js b/static/examples/7.x/go-back.js index e2417a2cf9d..ed6b1dbbc07 100755 --- a/static/examples/7.x/go-back.js +++ b/static/examples/7.x/go-back.js @@ -1,9 +1,11 @@ import * as React from 'react'; import { Button, View, Text } from 'react-native'; -import { NavigationContainer } from '@react-navigation/native'; +import { NavigationContainer, useNavigation } from '@react-navigation/native'; import { createNativeStackNavigator } from '@react-navigation/native-stack'; -function HomeScreen({ navigation }) { +function HomeScreen() { + const navigation = useNavigation(); + return ( Home Screen @@ -15,7 +17,9 @@ function HomeScreen({ navigation }) { ); } -function DetailsScreen({ navigation }) { +function DetailsScreen() { + const navigation = useNavigation(); + return ( Details Screen diff --git a/static/examples/7.x/multiple-navigate.js b/static/examples/7.x/multiple-navigate.js index 8e4ecc94b25..ddb83a07768 100755 --- a/static/examples/7.x/multiple-navigate.js +++ b/static/examples/7.x/multiple-navigate.js @@ -1,9 +1,11 @@ import * as React from 'react'; import { Button, View, Text } from 'react-native'; -import { NavigationContainer } from '@react-navigation/native'; +import { NavigationContainer, useNavigation } from '@react-navigation/native'; import { createNativeStackNavigator } from '@react-navigation/native-stack'; -function HomeScreen({ navigation }) { +function HomeScreen() { + const navigation = useNavigation(); + return ( Home Screen @@ -15,7 +17,9 @@ function HomeScreen({ navigation }) { ); } -function DetailsScreen({ navigation }) { +function DetailsScreen() { + const navigation = useNavigation(); + return ( Details Screen diff --git a/static/examples/7.x/multiple-push.js b/static/examples/7.x/multiple-push.js index 32c8f1126a9..21f2213a1b1 100755 --- a/static/examples/7.x/multiple-push.js +++ b/static/examples/7.x/multiple-push.js @@ -1,9 +1,11 @@ import * as React from 'react'; import { Button, View, Text } from 'react-native'; -import { NavigationContainer } from '@react-navigation/native'; +import { NavigationContainer, useNavigation } from '@react-navigation/native'; import { createNativeStackNavigator } from '@react-navigation/native-stack'; -function HomeScreen({ navigation }) { +function HomeScreen() { + const navigation = useNavigation(); + return ( Home Screen @@ -15,7 +17,9 @@ function HomeScreen({ navigation }) { ); } -function DetailsScreen({ navigation }) { +function DetailsScreen() { + const navigation = useNavigation(); + return ( Details Screen diff --git a/static/examples/7.x/new-screen.js b/static/examples/7.x/new-screen.js index 7d7e4991edb..21c7b472f92 100755 --- a/static/examples/7.x/new-screen.js +++ b/static/examples/7.x/new-screen.js @@ -1,9 +1,11 @@ import * as React from 'react'; import { Button, View, Text } from 'react-native'; -import { NavigationContainer } from '@react-navigation/native'; +import { NavigationContainer, useNavigation } from '@react-navigation/native'; import { createNativeStackNavigator } from '@react-navigation/native-stack'; -function HomeScreen({ navigation }) { +function HomeScreen() { + const navigation = useNavigation(); + return ( Home Screen diff --git a/static/examples/7.x/params-nested-navigators.js b/static/examples/7.x/params-nested-navigators.js index dbb8959679b..d2a20a7cad8 100755 --- a/static/examples/7.x/params-nested-navigators.js +++ b/static/examples/7.x/params-nested-navigators.js @@ -1,10 +1,12 @@ import * as React from 'react'; import { Button, View, Text } from 'react-native'; -import { NavigationContainer } from '@react-navigation/native'; +import { NavigationContainer, useNavigation } from '@react-navigation/native'; import { createNativeStackNavigator } from '@react-navigation/native-stack'; import { createDrawerNavigator } from '@react-navigation/drawer'; -function SettingsScreen({ route, navigation }) { +function SettingsScreen({ route }) { + const navigation = useNavigation(); + const { user } = route.params; return ( @@ -18,7 +20,9 @@ function SettingsScreen({ route, navigation }) { ); } -function ProfileScreen({ navigation }) { +function ProfileScreen() { + const navigation = useNavigation(); + return ( Profile Screen @@ -26,7 +30,9 @@ function ProfileScreen({ navigation }) { ); } -function HomeScreen({ navigation }) { +function HomeScreen() { + const navigation = useNavigation(); + return ( Home Screen diff --git a/static/examples/7.x/passing-params-back.js b/static/examples/7.x/passing-params-back.js index 5a2a6051c5d..3c392ef963e 100755 --- a/static/examples/7.x/passing-params-back.js +++ b/static/examples/7.x/passing-params-back.js @@ -1,9 +1,11 @@ import * as React from 'react'; import { Text, TextInput, View, Button } from 'react-native'; -import { NavigationContainer } from '@react-navigation/native'; +import { NavigationContainer, useNavigation } from '@react-navigation/native'; import { createNativeStackNavigator } from '@react-navigation/native-stack'; -function HomeScreen({ navigation, route }) { +function HomeScreen({ route }) { + const navigation = useNavigation(); + React.useEffect(() => { if (route.params?.post) { // Post updated, do something with `route.params.post` @@ -22,7 +24,8 @@ function HomeScreen({ navigation, route }) { ); } -function CreatePostScreen({ navigation, route }) { +function CreatePostScreen({ route }) { + const navigation = useNavigation(); const [postText, setPostText] = React.useState(''); return ( diff --git a/static/examples/7.x/passing-params.js b/static/examples/7.x/passing-params.js index 5a43e8c6d51..78a3586dd0e 100755 --- a/static/examples/7.x/passing-params.js +++ b/static/examples/7.x/passing-params.js @@ -1,9 +1,11 @@ import * as React from 'react'; import { Text, View, Button } from 'react-native'; -import { NavigationContainer } from '@react-navigation/native'; +import { NavigationContainer, useNavigation } from '@react-navigation/native'; import { createNativeStackNavigator } from '@react-navigation/native-stack'; -function HomeScreen({ navigation }) { +function HomeScreen() { + const navigation = useNavigation(); + return ( Home Screen @@ -21,7 +23,9 @@ function HomeScreen({ navigation }) { ); } -function DetailsScreen({ route, navigation }) { +function DetailsScreen({ route }) { + const navigation = useNavigation(); + /* 2. Get the param */ const { itemId } = route.params; const { otherParam } = route.params; diff --git a/static/examples/7.x/pop-to-top.js b/static/examples/7.x/pop-to-top.js index 83dd5f08a7c..4d108ad612e 100755 --- a/static/examples/7.x/pop-to-top.js +++ b/static/examples/7.x/pop-to-top.js @@ -1,9 +1,11 @@ import * as React from 'react'; import { Button, View, Text } from 'react-native'; -import { NavigationContainer } from '@react-navigation/native'; +import { NavigationContainer, useNavigation } from '@react-navigation/native'; import { createNativeStackNavigator } from '@react-navigation/native-stack'; -function HomeScreen({ navigation }) { +function HomeScreen() { + const navigation = useNavigation(); + return ( Home Screen @@ -15,7 +17,9 @@ function HomeScreen({ navigation }) { ); } -function DetailsScreen({ navigation }) { +function DetailsScreen() { + const navigation = useNavigation(); + return ( Details Screen diff --git a/versioned_docs/version-7.x/getting-started.md b/versioned_docs/version-7.x/getting-started.md index 235b8383cc3..ef013837367 100755 --- a/versioned_docs/version-7.x/getting-started.md +++ b/versioned_docs/version-7.x/getting-started.md @@ -114,9 +114,25 @@ When you use a navigator (such as stack navigator), you'll need to follow the in ::: -## Wrapping your app in `NavigationContainer` +## Setting up React Navigation -Now, we need to wrap the whole app in `NavigationContainer`. Usually you'd do this in your entry file, such as `index.js` or `App.js`: +Once you've installed and configured the dependencies, you can move on to setting up your project to use React Navigation. + +When using React Navigation, you configure [**navigators**](glossary-of-terms.md#navigator) in your app. Navigators handle the transition between screens in your app and provide UI such as header, tab bar etc. + +There are 2 primary ways to configure the navigators: + +### Static configuration + +The static configuration API has reduced boilerplate and simplifies things such as TypeScript types and deep linking. If you're staring a new project or are new to React Navigation, this is the **recommended way** to set up your app. + +To get started with static configuration, continue to ["Getting started with static API"](hello-react-navigation-static.md). + +### Dynamic configuration + +The dynamic configuration allows for more flexibility, but requires more boilerplate and configuration. + +To get started with dynamic configuration, first we need to wrap your app in `NavigationContainer`. Usually you'd do this in your entry file, such as `index.js` or `App.js`: ```js import * as React from 'react'; @@ -135,6 +151,4 @@ In a typical React Native app, the `NavigationContainer` should be only used onc ::: -Now you are ready to build and run your app on the device/simulator. - -Continue to ["Hello React Navigation"](hello-react-navigation.md) to start writing some code. +Continue to ["Getting started with dynamic API"](hello-react-navigation.md) to start writing some code. diff --git a/versioned_docs/version-7.x/hello-react-navigation-static.md b/versioned_docs/version-7.x/hello-react-navigation-static.md new file mode 100644 index 00000000000..bc420d0697e --- /dev/null +++ b/versioned_docs/version-7.x/hello-react-navigation-static.md @@ -0,0 +1,161 @@ +--- +id: hello-react-navigation-static +title: Static configuration +sidebar_label: Static configuration +--- + +In a web browser, there are multiple **pages** and you can **link to** the pages using an anchor (``) tag. Similarly, in React Native, you have multiple **screens** and you can **navigate** between them. + +React Navigation provides different types of navigators, such as the stack navigator, tab navigator, drawer navigator, etc. Each navigator provides a different way of transitioning between screens. They have a similar API for configuring them. + +The stack navigator is the most commonly used navigator. It resembles how you would expect multiple pages to work in a web browser. In this guide, let's start by demonstrating how to configure the native stack navigator. + +## Installing the native stack navigator library + +The libraries we've installed so far are the building blocks and shared foundations for navigators, and each navigator in React Navigation lives in its own library. To use the native stack navigator, we need to install [`@react-navigation/native-stack`](https://github.com/react-navigation/react-navigation/tree/main/packages/native-stack) : + +```bash npm2yarn +npm install @react-navigation/native-stack@next +``` + +> 💡 `@react-navigation/native-stack` depends on `react-native-screens` and the other libraries that we installed in [Getting started](getting-started.md). If you haven't installed those yet, head over to that page and follow the installation instructions. + +## Creating a native stack navigator + +`createNativeStackNavigator` is a function that takes a configuration object containing the screens and customization options. The screens are React Components that render the content displayed by the navigator. + +```js +// In App.js in a new project + +import * as React from 'react'; +import { View, Text } from 'react-native'; +import { createStaticNavigation } from '@react-navigation/native'; +import { createNativeStackNavigator } from '@react-navigation/native-stack'; + +function HomeScreen() { + return ( + + Home Screen + + ); +} + +const RootStack = createNativeStackNavigator({ + screens: { + Home: HomeScreen, + }, +}); + +const Navigation = createStaticNavigation(RootStack); + +function App() { + return ; +} + +export default App; +``` + +If you run this code, you will see a screen with an empty navigation bar and a grey content area containing your `HomeScreen` component (shown above). The styles you see for the navigation bar and the content area are the default configuration for a stack navigator, we'll learn how to configure those later. + +> The casing of the route name doesn't matter -- you can use lowercase `home` or capitalized `Home`, it's up to you. We prefer capitalizing our route names. + +### Configuring the navigator + +All of the route configuration is specified as props to our navigator. We haven't passed any props to our navigator, so it just uses the default configuration. + +Let's add a second screen to our native stack navigator and configure the `Home` screen to render first: + +```js +function DetailsScreen() { + return ( + + Details Screen + + ); +} + +const RootStack = createNativeStackNavigator({ + initialRouteName: 'Home', + screens: { + Home: HomeScreen, + Details: DetailsScreen, + }, +}); + +const Navigation = createStaticNavigation(RootStack); + +function App() { + return ; +} +``` + +Now our stack has two _routes_, a `Home` route and a `Details` route. A route can be specified by using the `Screen` component. The `Screen` component accepts a `name` prop which corresponds to the name of the route we will use to navigate, and a `component` prop which corresponds to the component it'll render. + +Here, the `Home` route corresponds to the `HomeScreen` component, and the `Details` route corresponds to the `DetailsScreen` component. The initial route for the stack is the `Home` route. Try changing it to `Details` and reload the app (React Native's Fast Refresh won't update changes from `initialRouteName`, as you might expect), notice that you will now see the `Details` screen. Then change it back to `Home` and reload once more. + +### Specifying options + +Each screen in the navigator can specify some options for the navigator, such as the title to render in the header. To specify the options, we'll change how we have specified the screen component: + +```js +const RootStack = createNativeStackNavigator({ + initialRouteName: 'Home', + screens: { + Home: { + screen: HomeScreen, + }, + Details: DetailsScreen, + }, +}); +``` + +Now, we can add an `options` property: + +```js +const RootStack = createNativeStackNavigator({ + initialRouteName: 'Home', + screens: { + Home: { + screen: HomeScreen, + options: { + title: 'Overview', + } + }, + Details: DetailsScreen, + }, +}); +``` + +Sometimes we will want to specify the same options for all of the screens in the navigator. For that, we can pass add a `screenOptions` property to the configuration. + +```js +const RootStack = createNativeStackNavigator({ + initialRouteName: 'Home', + screenOptions: { + headerStyle: { backgroundColor: 'tomato' }, + }, + screens: { + Home: { + screen: HomeScreen, + options: { + title: 'Overview', + } + }, + Details: DetailsScreen, + }, +}); +``` + +Here we have specified a `headerStyle` property. This will customize the styles of the header in all of the screens of the navigator. + +## What's next? + +The natural question at this point is: "how do I go from the `Home` route to the `Details` route?". That is covered in the [navigating section](navigating.md) under fundamentals. + +## Summary + +- React Native doesn't have a built-in API for navigation like a web browser does. React Navigation provides this for you, along with the iOS and Android gestures and animations to transition between screens. +- `createNativeStackNavigator` is a function that takes the screens configuration and renders our content. +- Each property under screens refers to the name of the route, and the value is the component to render for the route. +- To specify what the initial route in a stack is, provide an `initialRouteName` option for the navigator. +- To specify screen-specific options, we can specify an `options` property, and for common options, we can specify `screenOptions`. diff --git a/versioned_docs/version-7.x/hello-react-navigation.md b/versioned_docs/version-7.x/hello-react-navigation.md index b318c2c74ff..0d4c8184b57 100755 --- a/versioned_docs/version-7.x/hello-react-navigation.md +++ b/versioned_docs/version-7.x/hello-react-navigation.md @@ -1,7 +1,7 @@ --- id: hello-react-navigation -title: Hello React Navigation -sidebar_label: Hello React Navigation +title: Dynamic configuration +sidebar_label: Dynamic configuration --- In a web browser, you can link to different pages using an anchor (``) tag. When the user clicks on a link, the URL is pushed to the browser history stack. When the user presses the back button, the browser pops the item from the top of the history stack, so the active page is now the previously visited page. React Native doesn't have a built-in idea of a global history stack like a web browser does -- this is where React Navigation enters the story. @@ -155,4 +155,4 @@ The natural question at this point is: "how do I go from the `Home` route to the - `Stack.Navigator` is a component that takes route configuration as its children with additional props for configuration and renders our content. - Each `Stack.Screen` component takes a `name` prop which refers to the name of the route and `component` prop which specifies the component to render for the route. These are the 2 required props. - To specify what the initial route in a stack is, provide an `initialRouteName` as the prop for the navigator. -- To specify screen-specific options, we can pass an `options` prop to `Stack.Screen`, and for common options, we can pass `screenOptions` to `Stack.Navigator` +- To specify screen-specific options, we can pass an `options` prop to `Stack.Screen`, and for common options, we can pass `screenOptions` to `Stack.Navigator`. diff --git a/versioned_docs/version-7.x/navigating.md b/versioned_docs/version-7.x/navigating.md index 5177d0dd3b9..f0699f4ab04 100755 --- a/versioned_docs/version-7.x/navigating.md +++ b/versioned_docs/version-7.x/navigating.md @@ -4,7 +4,7 @@ title: Moving between screens sidebar_label: Moving between screens --- -In the previous section, ["Hello React Navigation"](hello-react-navigation.md), we defined a stack navigator with two routes (`Home` and `Details`), but we didn't learn how to let a user navigate from `Home` to `Details` (although we did learn how to change the _initial_ route in our code, but forcing our users to clone our repository and change the route in our code in order to see another screen is arguably among the worst user experiences one could imagine). +In the previous section, we defined a stack navigator with two routes (`Home` and `Details`), but we didn't learn how to let a user navigate from `Home` to `Details` (although we did learn how to change the _initial_ route in our code, but forcing our users to clone our repository and change the route in our code in order to see another screen is arguably among the worst user experiences one could imagine). If this was a web browser, we'd be able to write something like this: @@ -33,10 +33,12 @@ We'll do something similar to the latter, but rather than using a `window.locati ```js import * as React from 'react'; import { Button, View, Text } from 'react-native'; -import { NavigationContainer } from '@react-navigation/native'; +import { NavigationContainer, useNavigation } from '@react-navigation/native'; import { createNativeStackNavigator } from '@react-navigation/native-stack'; -function HomeScreen({ navigation }) { +function HomeScreen() { + const navigation = useNavigation(); + return ( Home Screen @@ -53,8 +55,8 @@ function HomeScreen({ navigation }) { Let's break this down: -- `navigation` - the `navigation` prop is passed in to every **screen component** ([definition](glossary-of-terms.md#screen-component)) in the native stack navigator (more about this later in ["The navigation prop in depth"](navigation-prop.md)). -- `navigate('Details')` - we call the `navigate` function (on the `navigation` prop — naming is hard!) with the name of the route that we'd like to move the user to. +- `navigation` - the `navigation` object is returned from the [`useNavigation`](use-navigation.md) hook (more about this later in ["The navigation prop in depth"](navigation-prop.md)). +- `navigate('Details')` - we call the `navigate` function (on the `navigation` object — naming is hard!) with the name of the route that we'd like to move the user to. :::note @@ -69,7 +71,9 @@ So we now have a stack with two routes: 1) the `Home` route 2) the `Details` rou ```js -function DetailsScreen({ navigation }) { +function DetailsScreen() { + const navigation = useNavigation(); + return ( Details Screen @@ -112,7 +116,9 @@ Sometimes you'll want to be able to programmatically trigger this behavior, and ```js -function DetailsScreen({ navigation }) { +function DetailsScreen() { + const navigation = useNavigation(); + return ( Details Screen @@ -138,7 +144,9 @@ Another common requirement is to be able to go back _multiple_ screens -- for ex ```js -function DetailsScreen({ navigation }) { +function DetailsScreen() { + const navigation = useNavigation(); + return ( Details Screen diff --git a/versioned_docs/version-7.x/params.md b/versioned_docs/version-7.x/params.md index 2f36f840ccc..37b4d9a4cd0 100755 --- a/versioned_docs/version-7.x/params.md +++ b/versioned_docs/version-7.x/params.md @@ -6,12 +6,11 @@ sidebar_label: Passing parameters to routes Remember when I said "more on that later when we talk about `params`!"? Well, the time has come. -Now that we know how to [create a stack navigator with some routes](hello-react-navigation.md) and [navigate between those routes](navigating.md), let's look at how we can pass data to routes when we navigate to them. +Now that we know how to create a stack navigator with some routes and [navigate between those routes](navigating.md), let's look at how we can pass data to routes when we navigate to them. There are two pieces to this: 1. Pass params to a route by putting them in an object as a second parameter to the `navigation.navigate` function: `navigation.navigate('RouteName', { /* params go here */ })` - 2. Read the params in your screen component: `route.params`. :::note @@ -23,7 +22,9 @@ We recommend that the params you pass are JSON-serializable. That way, you'll be ```js -function HomeScreen({ navigation }) { +function HomeScreen() { + const navigation = useNavigation(); + return ( Home Screen @@ -41,7 +42,9 @@ function HomeScreen({ navigation }) { ); } -function DetailsScreen({ route, navigation }) { +function DetailsScreen({ route }) { + const navigation = useNavigation(); + /* 2. Get the param */ const { itemId, otherParam } = route.params; return ( @@ -70,6 +73,19 @@ function DetailsScreen({ route, navigation }) { You can also pass some initial params to a screen. If you didn't specify any params when navigating to this screen, the initial params will be used. They are also shallow merged with any params that you pass. Initial params can be specified with an `initialParams` prop: +For static configuration: + +```js +{ + Details: { + screen: DetailsScreen, + initialParams: { itemId: 42 }, + }, +} +``` + +For dynamic configuration: + ```js @@ -109,7 +125,9 @@ To achieve this, you can use the `navigate` method, which acts like `goBack` if ```js -function HomeScreen({ navigation, route }) { +function HomeScreen({ route }) { + const navigation = useNavigation(); + React.useEffect(() => { if (route.params?.post) { // Post updated, do something with `route.params.post` @@ -128,7 +146,8 @@ function HomeScreen({ navigation, route }) { ); } -function CreatePostScreen({ navigation, route }) { +function CreatePostScreen({ route }) { + const navigation = useNavigation(); const [postText, setPostText] = React.useState(''); return ( diff --git a/versioned_docs/version-7.x/static-configuration.md b/versioned_docs/version-7.x/static-configuration.md index 0d2b0858d14..46ef65a61de 100644 --- a/versioned_docs/version-7.x/static-configuration.md +++ b/versioned_docs/version-7.x/static-configuration.md @@ -1,7 +1,7 @@ --- id: static-configuration -title: Getting started with static API -sidebar_label: Getting started +title: Overview of static API +sidebar_label: Overview --- React Navigation primarily uses a dynamic component based API. This provides a lot of flexibility, however there are a few drawbacks: diff --git a/versioned_sidebars/version-7.x-sidebars.json b/versioned_sidebars/version-7.x-sidebars.json index 64e3a3baaa7..ee8266e6a4c 100644 --- a/versioned_sidebars/version-7.x-sidebars.json +++ b/versioned_sidebars/version-7.x-sidebars.json @@ -9,10 +9,7 @@ "header-buttons", "nesting-navigators", "navigation-lifecycle", - "next-steps", - "glossary-of-terms", - "troubleshooting", - "limitations" + "next-steps" ], "Guides": [ "tab-based-navigation", @@ -41,6 +38,7 @@ "typescript", "redux-integration", "MST-integration", + "troubleshooting", "upgrading-from-6.x" ], "Static configuration": [ @@ -112,7 +110,9 @@ "more-resources" ], "Meta": [ + "glossary-of-terms", "pitch", + "limitations", "used-by", "contributing" ] From 716ea0d380617cfa62b4c1d5f070439a31d05ec1 Mon Sep 17 00:00:00 2001 From: Satyajit Sahoo Date: Tue, 19 Dec 2023 14:06:58 +0100 Subject: [PATCH 2/9] Use tabs for static vs dynamic --- versioned_docs/version-7.x/getting-started.md | 13 +- .../hello-react-navigation-static.md | 161 -------------- .../version-7.x/hello-react-navigation.md | 196 +++++++++++++++++- versioned_docs/version-7.x/params.md | 14 +- 4 files changed, 209 insertions(+), 175 deletions(-) delete mode 100644 versioned_docs/version-7.x/hello-react-navigation-static.md diff --git a/versioned_docs/version-7.x/getting-started.md b/versioned_docs/version-7.x/getting-started.md index ef013837367..7d07c0cb0d6 100755 --- a/versioned_docs/version-7.x/getting-started.md +++ b/versioned_docs/version-7.x/getting-started.md @@ -4,6 +4,9 @@ title: Getting started sidebar_label: Getting started --- +import Tabs from '@theme/Tabs'; +import TabItem from '@theme/TabItem'; + What follows within the _Fundamentals_ section of this documentation is a tour of the most important aspects of React Navigation. It should cover enough for you to know how to build your typical small mobile application, and give you the background that you need to dive deeper into the more advanced parts of React Navigation. ## Pre-requisites @@ -124,15 +127,15 @@ There are 2 primary ways to configure the navigators: ### Static configuration -The static configuration API has reduced boilerplate and simplifies things such as TypeScript types and deep linking. If you're staring a new project or are new to React Navigation, this is the **recommended way** to set up your app. +The static configuration API has reduced boilerplate and simplifies things such as TypeScript types and deep linking. If you're starting a new project or are new to React Navigation, this is the **recommended way** to set up your app. -To get started with static configuration, continue to ["Getting started with static API"](hello-react-navigation-static.md). +Continue to ["Hello React Navigation"](hello-react-navigation.md?config=static) to start writing some code with the Static API. ### Dynamic configuration -The dynamic configuration allows for more flexibility, but requires more boilerplate and configuration. +The dynamic configuration allows for more flexibility but requires more boilerplate and configuration. -To get started with dynamic configuration, first we need to wrap your app in `NavigationContainer`. Usually you'd do this in your entry file, such as `index.js` or `App.js`: +To get started with dynamic configuration, first, we need to wrap your app in `NavigationContainer`. Usually, you'd do this in your entry file, such as `index.js` or `App.js`: ```js import * as React from 'react'; @@ -151,4 +154,4 @@ In a typical React Native app, the `NavigationContainer` should be only used onc ::: -Continue to ["Getting started with dynamic API"](hello-react-navigation.md) to start writing some code. +Continue to ["Hello React Navigation"](hello-react-navigation.md?config=dynamic) to start writing some code with the Dynamic API. diff --git a/versioned_docs/version-7.x/hello-react-navigation-static.md b/versioned_docs/version-7.x/hello-react-navigation-static.md deleted file mode 100644 index bc420d0697e..00000000000 --- a/versioned_docs/version-7.x/hello-react-navigation-static.md +++ /dev/null @@ -1,161 +0,0 @@ ---- -id: hello-react-navigation-static -title: Static configuration -sidebar_label: Static configuration ---- - -In a web browser, there are multiple **pages** and you can **link to** the pages using an anchor (``) tag. Similarly, in React Native, you have multiple **screens** and you can **navigate** between them. - -React Navigation provides different types of navigators, such as the stack navigator, tab navigator, drawer navigator, etc. Each navigator provides a different way of transitioning between screens. They have a similar API for configuring them. - -The stack navigator is the most commonly used navigator. It resembles how you would expect multiple pages to work in a web browser. In this guide, let's start by demonstrating how to configure the native stack navigator. - -## Installing the native stack navigator library - -The libraries we've installed so far are the building blocks and shared foundations for navigators, and each navigator in React Navigation lives in its own library. To use the native stack navigator, we need to install [`@react-navigation/native-stack`](https://github.com/react-navigation/react-navigation/tree/main/packages/native-stack) : - -```bash npm2yarn -npm install @react-navigation/native-stack@next -``` - -> 💡 `@react-navigation/native-stack` depends on `react-native-screens` and the other libraries that we installed in [Getting started](getting-started.md). If you haven't installed those yet, head over to that page and follow the installation instructions. - -## Creating a native stack navigator - -`createNativeStackNavigator` is a function that takes a configuration object containing the screens and customization options. The screens are React Components that render the content displayed by the navigator. - -```js -// In App.js in a new project - -import * as React from 'react'; -import { View, Text } from 'react-native'; -import { createStaticNavigation } from '@react-navigation/native'; -import { createNativeStackNavigator } from '@react-navigation/native-stack'; - -function HomeScreen() { - return ( - - Home Screen - - ); -} - -const RootStack = createNativeStackNavigator({ - screens: { - Home: HomeScreen, - }, -}); - -const Navigation = createStaticNavigation(RootStack); - -function App() { - return ; -} - -export default App; -``` - -If you run this code, you will see a screen with an empty navigation bar and a grey content area containing your `HomeScreen` component (shown above). The styles you see for the navigation bar and the content area are the default configuration for a stack navigator, we'll learn how to configure those later. - -> The casing of the route name doesn't matter -- you can use lowercase `home` or capitalized `Home`, it's up to you. We prefer capitalizing our route names. - -### Configuring the navigator - -All of the route configuration is specified as props to our navigator. We haven't passed any props to our navigator, so it just uses the default configuration. - -Let's add a second screen to our native stack navigator and configure the `Home` screen to render first: - -```js -function DetailsScreen() { - return ( - - Details Screen - - ); -} - -const RootStack = createNativeStackNavigator({ - initialRouteName: 'Home', - screens: { - Home: HomeScreen, - Details: DetailsScreen, - }, -}); - -const Navigation = createStaticNavigation(RootStack); - -function App() { - return ; -} -``` - -Now our stack has two _routes_, a `Home` route and a `Details` route. A route can be specified by using the `Screen` component. The `Screen` component accepts a `name` prop which corresponds to the name of the route we will use to navigate, and a `component` prop which corresponds to the component it'll render. - -Here, the `Home` route corresponds to the `HomeScreen` component, and the `Details` route corresponds to the `DetailsScreen` component. The initial route for the stack is the `Home` route. Try changing it to `Details` and reload the app (React Native's Fast Refresh won't update changes from `initialRouteName`, as you might expect), notice that you will now see the `Details` screen. Then change it back to `Home` and reload once more. - -### Specifying options - -Each screen in the navigator can specify some options for the navigator, such as the title to render in the header. To specify the options, we'll change how we have specified the screen component: - -```js -const RootStack = createNativeStackNavigator({ - initialRouteName: 'Home', - screens: { - Home: { - screen: HomeScreen, - }, - Details: DetailsScreen, - }, -}); -``` - -Now, we can add an `options` property: - -```js -const RootStack = createNativeStackNavigator({ - initialRouteName: 'Home', - screens: { - Home: { - screen: HomeScreen, - options: { - title: 'Overview', - } - }, - Details: DetailsScreen, - }, -}); -``` - -Sometimes we will want to specify the same options for all of the screens in the navigator. For that, we can pass add a `screenOptions` property to the configuration. - -```js -const RootStack = createNativeStackNavigator({ - initialRouteName: 'Home', - screenOptions: { - headerStyle: { backgroundColor: 'tomato' }, - }, - screens: { - Home: { - screen: HomeScreen, - options: { - title: 'Overview', - } - }, - Details: DetailsScreen, - }, -}); -``` - -Here we have specified a `headerStyle` property. This will customize the styles of the header in all of the screens of the navigator. - -## What's next? - -The natural question at this point is: "how do I go from the `Home` route to the `Details` route?". That is covered in the [navigating section](navigating.md) under fundamentals. - -## Summary - -- React Native doesn't have a built-in API for navigation like a web browser does. React Navigation provides this for you, along with the iOS and Android gestures and animations to transition between screens. -- `createNativeStackNavigator` is a function that takes the screens configuration and renders our content. -- Each property under screens refers to the name of the route, and the value is the component to render for the route. -- To specify what the initial route in a stack is, provide an `initialRouteName` option for the navigator. -- To specify screen-specific options, we can specify an `options` property, and for common options, we can specify `screenOptions`. diff --git a/versioned_docs/version-7.x/hello-react-navigation.md b/versioned_docs/version-7.x/hello-react-navigation.md index 0d4c8184b57..f6ae5472399 100755 --- a/versioned_docs/version-7.x/hello-react-navigation.md +++ b/versioned_docs/version-7.x/hello-react-navigation.md @@ -1,9 +1,12 @@ --- id: hello-react-navigation -title: Dynamic configuration -sidebar_label: Dynamic configuration +title: Hello React Navigation +sidebar_label: Hello React Navigation --- +import Tabs from '@theme/Tabs'; +import TabItem from '@theme/TabItem'; + In a web browser, you can link to different pages using an anchor (``) tag. When the user clicks on a link, the URL is pushed to the browser history stack. When the user presses the back button, the browser pops the item from the top of the history stack, so the active page is now the previously visited page. React Native doesn't have a built-in idea of a global history stack like a web browser does -- this is where React Navigation enters the story. React Navigation's native stack navigator provides a way for your app to transition between screens and manage navigation history. If your app uses only one stack navigator then it is conceptually similar to how a web browser handles navigation state - your app pushes and pops items from the navigation stack as users interact with it, and this results in the user seeing different screens. A key difference between how this works in a web browser and in React Navigation is that React Navigation's native stack navigator provides the gestures and animations that you would expect on Android and iOS when navigating between routes in the stack. @@ -22,9 +25,50 @@ npm install @react-navigation/native-stack@next ### Creating a native stack navigator + + + +`createNativeStackNavigator` is a function that takes a configuration object containing the screens and customization options. The screens are React Components that render the content displayed by the navigator. + +`createStaticNavigation` is a function that takes the navigator defined earlier and returns a component that can be rendered in the app. It's only called once in the app. + +```js +// In App.js in a new project + +import * as React from 'react'; +import { View, Text } from 'react-native'; +import { createStaticNavigation } from '@react-navigation/native'; +import { createNativeStackNavigator } from '@react-navigation/native-stack'; + +function HomeScreen() { + return ( + + Home Screen + + ); +} + +const RootStack = createNativeStackNavigator({ + screens: { + Home: HomeScreen, + }, +}); + +const Navigation = createStaticNavigation(RootStack); + +function App() { + return ; +} + +export default App; +``` + + + + `createNativeStackNavigator` is a function that returns an object containing 2 properties: `Screen` and `Navigator`. Both of them are React components used for configuring the navigator. The `Navigator` should contain `Screen` elements as its children to define the configuration for routes. -`NavigationContainer` is a component which manages our navigation tree and contains the [navigation state](navigation-state.md). This component must wrap all navigators structure. Usually, we'd render this component at the root of our app, which is usually the component exported from `App.js`. +`NavigationContainer` is a component that manages our navigation tree and contains the [navigation state](navigation-state.md). This component must wrap all the navigators in the app. Usually, we'd render this component at the root of our app, which is usually the component exported from `App.js`. @@ -59,6 +103,9 @@ function App() { export default App; ``` + + + ![Basic app using stack navigator](/assets/navigators/stack/basic_stack_nav.png) If you run this code, you will see a screen with an empty navigation bar and a grey content area containing your `HomeScreen` component (shown above). The styles you see for the navigation bar and the content area are the default configuration for a stack navigator, we'll learn how to configure those later. @@ -75,6 +122,36 @@ All of the route configuration is specified as props to our navigator. We haven' Let's add a second screen to our native stack navigator and configure the `Home` screen to render first: + + + +```js +function DetailsScreen() { + return ( + + Details Screen + + ); +} + +const RootStack = createNativeStackNavigator({ + initialRouteName: 'Home', + screens: { + Home: HomeScreen, + Details: DetailsScreen, + }, +}); + +const Navigation = createStaticNavigation(RootStack); + +function App() { + return ; +} +``` + + + + ```js @@ -100,19 +177,81 @@ function App() { } ``` + + + Now our stack has two _routes_, a `Home` route and a `Details` route. A route can be specified by using the `Screen` component. The `Screen` component accepts a `name` prop which corresponds to the name of the route we will use to navigate, and a `component` prop which corresponds to the component it'll render. Here, the `Home` route corresponds to the `HomeScreen` component, and the `Details` route corresponds to the `DetailsScreen` component. The initial route for the stack is the `Home` route. Try changing it to `Details` and reload the app (React Native's Fast Refresh won't update changes from `initialRouteName`, as you might expect), notice that you will now see the `Details` screen. Then change it back to `Home` and reload once more. :::warning -The `component` prop accepts component, not a render function. Don't pass an inline function (e.g. `component={() => }`), or your component will unmount and remount losing all state when the parent component re-renders. See [Passing additional props](#passing-additional-props) for alternatives. +When using the dynamic API, the `component` prop accepts a component, not a render function. Don't pass an inline function (e.g. `component={() => }`), or your component will unmount and remount losing all state when the parent component re-renders. See [Passing additional props](#passing-additional-props) for alternatives. ::: ### Specifying options -Each screen in the navigator can specify some options for the navigator, such as the title to render in the header. These options can be passed in the `options` prop for each screen component: +Each screen in the navigator can specify some options for the navigator, such as the title to render in the header. + + + + +To specify the options, we'll change how we have specified the screen component: + +```js +const RootStack = createNativeStackNavigator({ + initialRouteName: 'Home', + screens: { + Home: { + screen: HomeScreen, + }, + Details: DetailsScreen, + }, +}); +``` + +Now, we can add an `options` property: + +```js +const RootStack = createNativeStackNavigator({ + initialRouteName: 'Home', + screens: { + Home: { + screen: HomeScreen, + options: { + title: 'Overview', + }, + }, + Details: DetailsScreen, + }, +}); +``` + +Sometimes we will want to specify the same options for all of the screens in the navigator. For that, we can add a `screenOptions` property to the configuration: + +```js +const RootStack = createNativeStackNavigator({ + initialRouteName: 'Home', + screenOptions: { + headerStyle: { backgroundColor: 'tomato' }, + }, + screens: { + Home: { + screen: HomeScreen, + options: { + title: 'Overview', + }, + }, + Details: DetailsScreen, + }, +}); +``` + + + + +Any customization options can be passed in the `options` prop for each screen component: @@ -124,10 +263,37 @@ Each screen in the navigator can specify some options for the navigator, such as /> ``` -Sometimes we will want to specify the same options for all of the screens in the navigator. For that, we can pass a `screenOptions` prop to the navigator. +Sometimes we will want to specify the same options for all of the screens in the navigator. For that, we can pass a `screenOptions` prop to the navigator: + +```js + + + + +``` + + + ### Passing additional props + + + +Passing additional props to a screen is not supported in the static API. + + + + Sometimes we might want to pass additional props to a screen. We can do that with 2 approaches: 1. Use [React context](https://reactjs.org/docs/context.html) and wrap the navigator with a context provider to pass data to the screens (recommended). @@ -145,14 +311,32 @@ By default, React Navigation applies optimizations to screen components to preve ::: + + + ## What's next? The natural question at this point is: "how do I go from the `Home` route to the `Details` route?". That is covered in the [next section](navigating.md). ## Summary + + + +- React Native doesn't have a built-in API for navigation like a web browser does. React Navigation provides this for you, along with the iOS and Android gestures and animations to transition between screens. +- `createNativeStackNavigator` is a function that takes the screens configuration and renders our content. +- Each property under screens refers to the name of the route, and the value is the component to render for the route. +- To specify what the initial route in a stack is, provide an `initialRouteName` option for the navigator. +- To specify screen-specific options, we can specify an `options` property, and for common options, we can specify `screenOptions`. + + + + - React Native doesn't have a built-in API for navigation like a web browser does. React Navigation provides this for you, along with the iOS and Android gestures and animations to transition between screens. - `Stack.Navigator` is a component that takes route configuration as its children with additional props for configuration and renders our content. - Each `Stack.Screen` component takes a `name` prop which refers to the name of the route and `component` prop which specifies the component to render for the route. These are the 2 required props. - To specify what the initial route in a stack is, provide an `initialRouteName` as the prop for the navigator. - To specify screen-specific options, we can pass an `options` prop to `Stack.Screen`, and for common options, we can pass `screenOptions` to `Stack.Navigator`. + + + diff --git a/versioned_docs/version-7.x/params.md b/versioned_docs/version-7.x/params.md index 37b4d9a4cd0..105029226a2 100755 --- a/versioned_docs/version-7.x/params.md +++ b/versioned_docs/version-7.x/params.md @@ -4,6 +4,9 @@ title: Passing parameters to routes sidebar_label: Passing parameters to routes --- +import Tabs from '@theme/Tabs'; +import TabItem from '@theme/TabItem'; + Remember when I said "more on that later when we talk about `params`!"? Well, the time has come. Now that we know how to create a stack navigator with some routes and [navigate between those routes](navigating.md), let's look at how we can pass data to routes when we navigate to them. @@ -71,9 +74,10 @@ function DetailsScreen({ route }) { ## Initial params -You can also pass some initial params to a screen. If you didn't specify any params when navigating to this screen, the initial params will be used. They are also shallow merged with any params that you pass. Initial params can be specified with an `initialParams` prop: +You can also pass some initial params to a screen. If you didn't specify any params when navigating to this screen, the initial params will be used. They are also shallow merged with any params that you pass. Initial params can be specified in `initialParams`: -For static configuration: + + ```js { @@ -84,7 +88,8 @@ For static configuration: } ``` -For dynamic configuration: + + @@ -96,6 +101,9 @@ For dynamic configuration: /> ``` + + + ## Updating params Screens can also update their params, like they can update their state. The `navigation.setParams` method lets you update the params of a screen. Refer to the [API reference for `setParams`](navigation-prop.md#setparams) for more details. From 13d2018acd4169c7d0aceece36a2684d5ba5e5e1 Mon Sep 17 00:00:00 2001 From: Satyajit Sahoo Date: Wed, 20 Dec 2023 06:15:39 +0100 Subject: [PATCH 3/9] Use 'object' instead 'prop' termibology for navigation & route --- .../version-7.x/bottom-tab-navigator.md | 4 +- .../version-7.x/connecting-navigation-prop.md | 48 ---------------- .../version-7.x/custom-navigators.md | 2 +- versioned_docs/version-7.x/custom-routers.md | 2 +- .../version-7.x/drawer-navigator.md | 4 +- versioned_docs/version-7.x/getting-started.md | 4 +- .../version-7.x/glossary-of-terms.md | 55 ++++++------------- versioned_docs/version-7.x/group.md | 2 +- versioned_docs/version-7.x/headers.md | 4 +- .../version-7.x/material-top-tab-navigator.md | 4 +- .../version-7.x/multiple-drawers.md | 6 +- .../version-7.x/native-stack-navigator.md | 4 +- .../navigating-without-navigation-prop.md | 2 +- versioned_docs/version-7.x/navigating.md | 6 +- .../version-7.x/navigation-container.md | 2 +- .../version-7.x/navigation-context.md | 2 +- .../version-7.x/navigation-events.md | 6 +- .../version-7.x/navigation-lifecycle.md | 2 +- ...avigation-prop.md => navigation-object.md} | 20 +++---- .../version-7.x/nesting-navigators.md | 10 ++-- versioned_docs/version-7.x/params.md | 4 +- .../{route-prop.md => route-object.md} | 6 +- versioned_docs/version-7.x/screen-options.md | 8 +-- versioned_docs/version-7.x/screen.md | 4 +- versioned_docs/version-7.x/stack-navigator.md | 4 +- .../version-7.x/static-api-reference.md | 4 +- versioned_docs/version-7.x/typescript.md | 4 +- .../version-7.x/use-link-builder.md | 2 +- versioned_docs/version-7.x/use-navigation.md | 8 +-- versioned_docs/version-7.x/use-route.md | 2 +- versioned_sidebars/version-7.x-sidebars.json | 5 +- 31 files changed, 84 insertions(+), 156 deletions(-) delete mode 100755 versioned_docs/version-7.x/connecting-navigation-prop.md rename versioned_docs/version-7.x/{navigation-prop.md => navigation-object.md} (89%) rename versioned_docs/version-7.x/{route-prop.md => route-object.md} (91%) diff --git a/versioned_docs/version-7.x/bottom-tab-navigator.md b/versioned_docs/version-7.x/bottom-tab-navigator.md index 35ac873c811..1582b919c58 100755 --- a/versioned_docs/version-7.x/bottom-tab-navigator.md +++ b/versioned_docs/version-7.x/bottom-tab-navigator.md @@ -53,7 +53,7 @@ The `Tab.Navigator` component accepts following props: #### `id` -Optional unique ID for the navigator. This can be used with [`navigation.getParent`](navigation-prop.md#getparent) to refer to this navigator in a child navigator. +Optional unique ID for the navigator. This can be used with [`navigation.getParent`](navigation-object.md#getparent) to refer to this navigator in a child navigator. #### `initialRouteName` @@ -442,7 +442,7 @@ React.useEffect(() => { ### Helpers -The tab navigator adds the following methods to the navigation prop: +The tab navigator adds the following methods to the navigation object: #### `jumpTo` diff --git a/versioned_docs/version-7.x/connecting-navigation-prop.md b/versioned_docs/version-7.x/connecting-navigation-prop.md deleted file mode 100755 index 628cedd792e..00000000000 --- a/versioned_docs/version-7.x/connecting-navigation-prop.md +++ /dev/null @@ -1,48 +0,0 @@ ---- -id: connecting-navigation-prop -title: Access the navigation prop from any component -sidebar_label: Access the navigation prop from any component ---- - -[`useNavigation`](use-navigation.md) is a hook which gives access to the `navigation` object. It's useful when you cannot pass the `navigation` prop into the component directly, or don't want to pass it in case of a deeply nested child. - -An ordinary component that is not a screen component will not receive the navigation prop automatically. For example in this `GoToButton` component: - -```js -import * as React from 'react'; -import { Button } from 'react-native'; - -function GoToButton({ navigation, screenName }) { - return ( -