屏幕
屏幕表示导航器中的路由。屏幕的配置包含路由的组件、选项、事件监听器等。
¥A screen represents routes in a navigator. A screen's configuration contains the component for the route, options, event listeners, etc.
- Static
- Dynamic
可以在导航器配置中的 screens
键下定义屏幕:
¥Screens can be defined under the screens
key in the navigator configuration:
const MyStack = createNativeStackNavigator({
screens: {
Home: HomeScreen,
Profile: ProfileScreen,
},
});
createXNavigator
函数返回 Screen
组件。创建导航器后,它可以用作 Navigator
组件的子组件:
¥A Screen
component is returned from a createXNavigator
function. After creating the navigator, it can be used as children of the Navigator
component:
const Stack = createNativeStackNavigator();
function MyStack() {
return (
<Stack.Navigator>
<Stack.Screen name="Home" component={HomeScreen} />
<Stack.Screen name="Profile" component={ProfileScreen} />
</Stack.Navigator>
);
}
你至少需要提供一个名称和一个要为每个屏幕渲染的组件。
¥You need to provide at least a name and a component to render for each screen.
配置
¥Configuration
名称
¥Name
用于屏幕的名称。
¥The name to use for the screen.
- Static
- Dynamic
screens
对象中的键用作名称:
¥The key in the screens
object is used as the name:
const Stack = createNativeStackNavigator({
screens: {
Profile: {
screen: ProfileScreen,
},
},
});
它可以在 name
属性中传递给 Screen
组件:
¥It can be passed in the name
prop to the Screen
component:
<Stack.Screen
name="Profile"
component={ProfileScreen}
/>
该名称用于导航到屏幕:
¥This name is used to navigate to the screen:
navigation.navigate('Profile');
它还用于 route
中的 name
属性。
¥It is also used for the name
property in the route
.
虽然它受支持,但我们建议避免在屏幕名称中使用空格或特殊字符并保持其简单。
¥While it is supported, we recommend avoiding spaces or special characters in screen names and keeping them simple.
选项
¥Options
选项用于配置屏幕在导航器中的显示方式。它接受一个对象或返回一个对象的函数:
¥Options are used to configure how the screen gets presented in the navigator. It accepts either an object or a function returning an object:
- Static
- Dynamic
const Stack = createNativeStackNavigator({
screens: {
Profile: {
screen: ProfileScreen,
options: {
title: 'Awesome app',
},
},
},
});
<Stack.Screen
name="Profile"
component={ProfileScreen}
options={{
title: 'Awesome app',
}}
/>
当你传递一个函数时,它将接收 route
、navigation
和 theme
作为参数:
¥When you pass a function, it'll receive the route
, navigation
and theme
as arguments:
- Static
- Dynamic
const Stack = createNativeStackNavigator({
screens: {
Profile: {
screen: ProfileScreen,
options: ({ route, navigation, theme }) => ({
title: route.params.userId,
}),
},
},
});
<Stack.Screen
name="Profile"
component={ProfileScreen}
options={({ route, navigation }) => ({
title: route.params.userId,
})}
/>
有关更多详细信息和示例,请参阅 屏幕选项。
¥See Options for screens for more details and examples.
初始参数
¥Initial params
初始参数用作屏幕的默认参数。如果屏幕用作 initialRouteName
,它将包含 initialParams
的参数。如果你导航到新屏幕,传递的参数将与初始参数浅层合并。
¥Initial params are used as the default params 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.
- Static
- Dynamic
const Stack = createNativeStackNavigator({
screens: {
Details: {
screen: DetailsScreen,
initialParams: { itemId: 42 },
},
},
});
<Stack.Screen
name="Details"
component={DetailsScreen}
initialParams={{ itemId: 42 }}
/>
ID
屏幕可以有一个 ID 来唯一地标识它。当你想要确保具有相同 ID 的屏幕不会在堆栈中多次出现时,这很有用。
¥A screen can have an ID to identify it uniquely. This is useful when you want to ensure that the screen with the same ID doesn't appear multiple times in the stack.
这可以通过指定 getId
回调来完成。它接收一个带有路由参数的对象:
¥This can be done by specifying the getId
callback. It receives an object with the route params:
- Static
- Dynamic
const Stack = createNativeStackNavigator({
screens: {
Profile: {
screen: ProfileScreen,
getId: ({ params }) => params.userId,
},
},
});
<Stack.Screen
name="Profile"
component={ProfileScreen}
getId={({ params }) => params.userId}
/>
默认情况下,如果屏幕名称匹配,navigate('ScreenName', params)
将更新当前屏幕,否则将在堆栈导航器中添加新屏幕。因此,如果你在 ScreenName
上并再次导航到 ScreenName
,即使参数不同,它也不会添加新屏幕 - 它将使用新参数更新当前屏幕:
¥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:
// Let's say you're on `Home` screen
// Then you navigate to `Profile` screen with `userId: 1`
navigation.navigate('Profile', { userId: 1 });
// Now the stack will have: `Home` -> `Profile` with `userId: 1`
// Then you navigate to `Profile` screen again with `userId: 2`
navigation.navigate('Profile', { userId: 2 });
// The stack will now have: `Home` -> `Profile` with `userId: 2`
如果指定 getId
并且不返回 undefined
,则屏幕由屏幕名称和返回的 ID 来标识。这意味着如果你在 ScreenName
上并使用不同的参数再次导航到 ScreenName
- 并从 getId
回调返回不同的 ID,它将向堆栈添加一个新屏幕:
¥If you specify getId
and it doesn't return undefined
, the screen is identified by both the screen name and the returned ID. That means that if you're on ScreenName
and navigate to ScreenName
again with different params - and return a different ID from the getId
callback, it'll add a new screen to the stack:
// Let's say you're on `Home` screen
// Then you navigate to `Profile` screen with `userId: 1`
navigation.navigate('Profile', { userId: 1 });
// Now the stack will have: `Home` -> `Profile` with `userId: 1`
// Then you navigate to `Profile` screen again with `userId: 2`
navigation.navigate('Profile', { userId: 2 });
// The stack will now have: `Home` -> `Profile` with `userId: 1` -> `Profile` with `userId: 2`
getId
回调还可用于确保具有相同 ID 的屏幕不会在堆栈中多次出现:
¥The getId
callback can also be used to ensure that the screen with the same ID doesn't appear multiple times in the stack:
// Let's say you have a stack with the screens: `Home` -> `Profile` with `userId: 1` -> `Settings`
// Then you navigate to `Profile` screen with `userId: 1` again
navigation.navigate('Profile', { userId: 1 });
// Now the stack will have: `Home` -> `Profile` with `userId: 1`
在上面的示例中,params.userId
用作 ID,后续导航到具有相同 userId
的屏幕时将导航到现有屏幕,而不是向堆栈添加新屏幕。如果导航使用不同的 userId
,那么它将添加一个新屏幕。
¥In the above examples, params.userId
is used as an ID, subsequent navigation to the screen with the same userId
will navigate to the existing screen instead of adding a new one to the stack. If the navigation was with a different userId
, then it'll add a new screen.
如果在选项卡或抽屉式导航器中指定了 getId
,则当 ID 更改时屏幕将重新安装。
¥If getId
is specified in a tab or drawer navigator, the screen will remount if the ID changes.
组件
¥Component
每个屏幕都必须指定要为该路由渲染的组件。
¥Each screen must specify a component to render for that route.
- Static
- Dynamic
它可以在屏幕配置中的 screen
属性下传递:
¥It can be passed under the screen
property in the screen configuration:
const Stack = createNativeStackNavigator({
screens: {
Profile: {
screen: ProfileScreen,
},
},
});
component
它可以在 component
属性中传递给 Screen
组件:
¥It can be passed in the component
prop to the Screen
component:
<Stack.Screen
name="Profile"
component={ProfileScreen}
/>
getComponent
也可以在 getComponent
prop 中传递一个函数来延迟评估组件:
¥It's also possible to pass a function in the getComponent
prop to lazily evaluate the component:
<Stack.Screen
name="Profile"
getComponent={() => require('./ProfileScreen').default}
/>
如果你希望在需要时延迟评估 ProfileScreen
模块,你可以使用此方法而不是 component
属性。当使用 内存束 来提高初始负载时,这尤其有用。
¥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 to improve initial load.
children
另一种方法是传递渲染回调以返回用于屏幕的 React Element:
¥Another way is to pass a render callback to return React Element to use for the screen:
<Stack.Screen name="Profile">
{(props) => <ProfileScreen {...props} />}
</Stack.Screen>
如果你需要传递其他属性,可以使用此方法代替 component
属性。尽管我们建议使用 React 上下文 来传递数据。
¥You can use this approach instead of the component
prop if you need to pass additional props. Though we recommend using React context for passing data instead.
默认情况下,React Navigation 会对屏幕组件进行优化,以防止不必要的渲染。使用渲染回调可以消除这些优化。因此,如果你使用渲染回调,则需要确保对屏幕组件使用 React.memo
或 React.PureComponent
以避免出现性能问题。
¥By default, React Navigation applies optimizations to screen components to prevent unnecessary renders. Using a render callback removes those optimizations. So if you use a render callback, you'll need to ensure that you use React.memo
or React.PureComponent
for your screen components to avoid performance issues.
布局
¥Layout
布局是屏幕的封装器。它使为屏幕提供诸如错误边界和悬念回退之类的内容变得更加容易:
¥A layout is a wrapper around the screen. It makes it easier to provide things such as an error boundary and suspense fallback for a screen:
- Static
- Dynamic
const Stack = createNativeStackNavigator({
screens: {
Profile: {
screen: ProfileScreen,
layout: ({ children }) => (
<ErrorBoundary>
<React.Suspense
fallback={
<View style={styles.fallback}>
<Text style={styles.text}>Loading…</Text>
</View>
}
>
{children}
</React.Suspense>
</ErrorBoundary>
),
},
},
});
<Stack.Screen
name="MyScreen"
component={MyScreenComponent}
layout={({ children }) => (
<ErrorBoundary>
<React.Suspense
fallback={
<View style={styles.fallback}>
<Text style={styles.text}>Loading…</Text>
</View>
}
>
{children}
</React.Suspense>
</ErrorBoundary>
)}
/>
要为所有多个屏幕指定布局,你可以在 group 或 navigator 中使用 screenLayout
。
¥To specify a layout for all multiple screens, you can use screenLayout
in a group or navigator.
导航键
¥Navigation key
导航键是此屏幕的可选键。这不需要是唯一的。如果键发生更改,则具有此名称的现有屏幕将被删除(如果在堆栈导航器中使用)或重置(如果在选项卡或抽屉导航器中使用)。
¥A navigation key is an optional key for this screen. This doesn't need to be unique. If the key changes, existing screens with this name will be removed (if used in a stack navigator) or reset (if used in a tab or drawer navigator).
当我们希望在条件发生变化时删除或重置某些屏幕时,这将很有用:
¥This can be useful when we have some screens that we want to be removed or reset when the condition changes:
- Static
- Dynamic
const Stack = createNativeStackNavigator({
screens: {
Profile: {
screen: ProfileScreen,
navigationKey: 'user',
},
},
});
对于静态 API,我们建议对每个屏幕使用 groups
而不是 navigationKey
,因为你可以使用 if
属性动态添加或删除组。
¥For the static API, we recommend using the groups
instead of the navigationKey
for each screen as you can dynamically add or remove groups with the if
property.
<Stack.Screen
navigationKey={isSignedIn ? 'user' : 'guest'}
name="Profile"
component={ProfileScreen}
/>
事件监听器
¥Event listeners
事件监听器可用于订阅为屏幕发出的各种事件。详细信息请参见 Screen
上的 listeners
属性。
¥Event listeners can be used to subscribe to various events emitted for the screen. See listeners
prop on Screen
for more details.