Skip to content

Migrate 'Screen' examples to static API in v7 #1323

New issue

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

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

Already on GitHub? Sign in to your account

Merged
merged 2 commits into from
Feb 26, 2024
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
195 changes: 194 additions & 1 deletion versioned_docs/version-7.x/screen.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,35 +4,90 @@ title: Screen
sidebar_label: Screen
---

import Tabs from '@theme/Tabs';
import TabItem from '@theme/TabItem';

`Screen` components are used to configure various aspects of screens inside a navigator.

A `Screen` is returned from a `createXNavigator` function:

<Tabs groupId="config" queryString="config">
<TabItem value="static" label="Static" default>

```js
const Stack = createNativeStackNavigator({
screens: {
/* content */
},
});
```

</TabItem>
<TabItem value="dynamic" label="Dynamic" default>

```js
const Stack = createNativeStackNavigator(); // Stack contains Screen & Navigator properties
```

</TabItem>
</Tabs>

After creating the navigator, it can be used as children of the `Navigator` component:

<Tabs groupId="config" queryString="config">
<TabItem value="static" label="Static" default>

```js
const Stack = createNativeStackNavigator({
screens: {
Home: HomeScreen,
Profile: ProfileScreen,
},
});
```

</TabItem>
<TabItem value="dynamic" label="Dynamic" default>

```js
<Stack.Navigator>
<Stack.Screen name="Home" component={HomeScreen} />
<Stack.Screen name="Profile" component={ProfileScreen} />
</Stack.Navigator>
```

</TabItem>
</Tabs>

You need to provide at least a name and a component to render for each screen.

## Props

### `name`

The name to use for the screen. It accepts a string:
The name to use for the screen. In dynamic approach it accepts a string:

<Tabs groupId="config" queryString="config">
<TabItem value="static" label="Static" default>

```js
const Stack = createNativeStackNavigator({
screens: {
Profile: ProfileScreen,
},
});
```

</TabItem>
<TabItem value="dynamic" label="Dynamic" default>

```js
<Stack.Screen name="Profile" component={ProfileScreen} />
```

</TabItem>
</Tabs>

This name is used to navigate to the screen:

```js
Expand All @@ -47,6 +102,25 @@ While it is supported, we recommend to avoid spaces or special characters in scr

Options to configure how the screen gets presented in the navigator. It accepts either an object or a function returning an object:

<Tabs groupId="config" queryString="config">
<TabItem value="static" label="Static" default>

```js
const Stack = createNativeStackNavigator({
screens: {
Profile: {
screen: ProfileScreen,
options: {
title: 'Awesome app',
},
},
},
});
```

</TabItem>
<TabItem value="dynamic" label="Dynamic" default>

```js
<Stack.Screen
name="Profile"
Expand All @@ -57,8 +131,30 @@ Options to configure how the screen gets presented in the navigator. It accepts
/>
```

</TabItem>
</Tabs>

When you pass a function, it'll receive the [`route`](route-object.md) and [`navigation`](navigation-object.md):

<Tabs groupId="config" queryString="config">
<TabItem value="static" label="Static" default>

```js
const Stack = createNativeStackNavigator({
screens: {
Profile: {
screen: ProfileScreen,
options: ({ route, navigation }) => ({
title: route.params.userId,
}),
},
},
});
```

</TabItem>
<TabItem value="dynamic" label="Dynamic" default>

```js
<Stack.Screen
name="Profile"
Expand All @@ -69,12 +165,32 @@ When you pass a function, it'll receive the [`route`](route-object.md) and [`nav
/>
```

</TabItem>
</Tabs>

See [Options for screens](screen-options.md) for more details and examples.

### `initialParams`

Initial params to use for the screen. If a screen is used as `initialRouteName`, it'll contain the params from `initialParams`. If you navigate to a new screen, the params passed are shallow merged with the initial params.

<Tabs groupId="config" queryString="config">
<TabItem value="static" label="Static" default>

```js
const Stack = createNativeStackNavigator({
screens: {
Details: {
screen: DetailsScreen,
initialParams: { itemId: 42 },
},
},
});
```

</TabItem>
<TabItem value="dynamic" label="Dynamic" default>

```js
<Stack.Screen
name="Details"
Expand All @@ -83,10 +199,30 @@ Initial params to use for the screen. If a screen is used as `initialRouteName`,
/>
```

</TabItem>
</Tabs>

### `getId`

Callback to return an unique ID to use for the screen. It receives an object with the route params:

<Tabs groupId="config" queryString="config">
<TabItem value="static" label="Static" default>

```js
const Stack = createNativeStackNavigator({
screens: {
Profile: {
screen: ProfileScreen,
getId: ({ params }) => params.userId,
},
},
});
```

</TabItem>
<TabItem value="dynamic" label="Dynamic" default>

```js
<Stack.Screen
name="Profile"
Expand All @@ -95,6 +231,9 @@ Callback to return an unique ID to use for the screen. It receives an object wit
/>
```

</TabItem>
</Tabs>

By default, `navigate('ScreenName', params)` updates the current screen if the screen name matches, otherwise adds a new screen in a stack navigator. So if you're on `ScreenName` and navigate to `ScreenName` again, it won't add a new screen even if the params are different - it'll update the current screen with the new params instead:

```js
Expand Down Expand Up @@ -143,21 +282,55 @@ If `getId` is specified in a tab or drawer navigator, the screen will remount if

The React Component to render for the screen:

<Tabs groupId="config" queryString="config">
<TabItem value="static" label="Static" default>

```js
const Stack = createNativeStackNavigator({
screens: {
Profile: ProfileScreen,
},
});
```

</TabItem>
<TabItem value="dynamic" label="Dynamic" default>

```js
<Stack.Screen name="Profile" component={ProfileScreen} />
```

</TabItem>
</Tabs>

### `getComponent`

Callback to return the React Component to render for the screen:

<Tabs groupId="config" queryString="config">
<TabItem value="static" label="Static" default>

```js
const Stack = createNativeStackNavigator({
screens: {
Profile: () => require('./ProfileScreen').default,
},
});
```

</TabItem>
<TabItem value="dynamic" label="Dynamic" default>

```js
<Stack.Screen
name="Profile"
getComponent={() => require('./ProfileScreen').default}
/>
```

</TabItem>
</Tabs>

You can use this approach instead of the `component` prop if you want the `ProfileScreen` module to be lazily evaluated when needed. This is especially useful when using [ram bundles](https://reactnative.dev/docs/ram-bundles-inline-requires) to improve initial load.

### `children`
Expand All @@ -184,6 +357,23 @@ Optional key for this screen. This doesn't need to be unique. If the key changes

This can be useful when we have some screens which we want to be removed or reset when the condition changes:

<Tabs groupId="config" queryString="config">
<TabItem value="static" label="Static" default>

```js
const Stack = createNativeStackNavigator({
screens: {
Profile: {
screen: ProfileScreen,
navigationKey: isSignedIn ? 'user' : 'guest',
},
},
});
```

</TabItem>
<TabItem value="dynamic" label="Dynamic" default>

```js
<Stack.Screen
navigationKey={isSignedIn ? 'user' : 'guest'}
Expand All @@ -192,6 +382,9 @@ This can be useful when we have some screens which we want to be removed or rese
/>
```

</TabItem>
</Tabs>

### `listeners`

Event listeners to subscribe to. See [`listeners` prop on `Screen`](navigation-events.md#listeners-prop-on-screen) for more details.