Screen
屏幕代表导航器中的路由。屏幕的配置包含路由的组件、选项、事件监听器等。
- 静态
- 动态
屏幕可以在导航器配置的 screens
键下定义
const MyStack = createNativeStackNavigator({
screens: {
Home: HomeScreen,
Profile: ProfileScreen,
},
});
Screen
组件从 createXNavigator
函数返回。创建导航器后,它可以作为 Navigator
组件的子组件使用
const Stack = createNativeStackNavigator();
function MyStack() {
return (
<Stack.Navigator>
<Stack.Screen name="Home" component={HomeScreen} />
<Stack.Screen name="Profile" component={ProfileScreen} />
</Stack.Navigator>
);
}
你需要为每个屏幕至少提供一个名称和一个要渲染的组件。
配置
名称
屏幕要使用的名称。
- 静态
- 动态
screens
对象中的键用作名称
const Stack = createNativeStackNavigator({
screens: {
Profile: {
screen: ProfileScreen,
},
},
});
它可以作为 name
属性传递给 Screen
组件
<Stack.Screen
name="Profile"
component={ProfileScreen}
/>
此名称用于导航到屏幕
navigation.navigate('Profile');
它也用于 route
中的 name
属性。
虽然支持,但我们建议避免在屏幕名称中使用空格或特殊字符,并保持简洁。
选项
选项用于配置屏幕在导航器中的呈现方式。它接受对象或返回对象的函数
- 静态
- 动态
const Stack = createNativeStackNavigator({
screens: {
Profile: {
screen: ProfileScreen,
options: {
title: 'Awesome app',
},
},
},
});
<Stack.Screen
name="Profile"
component={ProfileScreen}
options={{
title: 'Awesome app',
}}
/>
当您传递一个函数时,它将接收 route
、navigation
和 theme
作为参数
- 静态
- 动态
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,
})}
/>
有关更多详细信息和示例,请参阅屏幕的选项。
初始参数
初始参数用作屏幕的默认参数。如果屏幕用作 initialRouteName
,它将包含来自 initialParams
的参数。如果您导航到新屏幕,则传递的参数将与初始参数浅合并。
- 静态
- 动态
const Stack = createNativeStackNavigator({
screens: {
Details: {
screen: DetailsScreen,
initialParams: { itemId: 42 },
},
},
});
<Stack.Screen
name="Details"
component={DetailsScreen}
initialParams={{ itemId: 42 }}
/>
ID
屏幕可以有一个 ID 来唯一标识它。当您想确保具有相同 ID 的屏幕不会在堆栈中多次出现时,这很有用。
这可以通过指定 getId
回调来完成。它接收一个包含路由参数的对象
- 静态
- 动态
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
,即使参数不同,它也不会添加新屏幕 - 而是使用新参数更新当前屏幕
// 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,它将向堆栈添加一个新屏幕
// 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 的屏幕不会在堆栈中多次出现
// 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
,则它将添加一个新屏幕。
如果在标签或抽屉导航器中指定了 getId
,则屏幕将在 ID 更改时重新挂载。
组件
每个屏幕都必须指定一个要为该路由渲染的组件。
- 静态
- 动态
它可以作为屏幕配置中的 screen
属性传递
const Stack = createNativeStackNavigator({
screens: {
Profile: {
screen: ProfileScreen,
},
},
});
component
它可以作为 component
属性传递给 Screen
组件
<Stack.Screen
name="Profile"
component={ProfileScreen}
/>
getComponent
也可以在 getComponent
属性中传递一个函数来延迟评估组件
<Stack.Screen
name="Profile"
getComponent={() => require('./ProfileScreen').default}
/>
如果您希望在需要时延迟评估 ProfileScreen
模块,则可以使用此方法代替 component
属性。当使用 ram bundles 来提高初始加载速度时,这尤其有用。
children
另一种方法是传递一个渲染回调以返回 React 元素用于屏幕
<Stack.Screen name="Profile">
{(props) => <ProfileScreen {...props} />}
</Stack.Screen>
如果您需要传递额外的 props,则可以使用此方法代替 component
属性。但是,我们建议使用 React context 来传递数据。
默认情况下,React Navigation 对屏幕组件应用优化以防止不必要的渲染。使用渲染回调会删除这些优化。因此,如果您使用渲染回调,则需要确保为屏幕组件使用 React.memo
或 React.PureComponent
,以避免性能问题。
布局
布局是屏幕周围的包装器。它可以更轻松地为屏幕提供诸如错误边界和 suspense fallback 之类的东西,或者用额外的 UI 包装屏幕。
它接受一个返回 React 元素的函数
- 静态
- 动态
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>
)}
/>
导航键
导航键是此屏幕的可选键。这不需要是唯一的。如果键更改,则具有此名称的现有屏幕将被删除(如果在堆栈导航器中使用)或重置(如果在标签或抽屉导航器中使用)。
当我们需要在条件更改时删除或重置某些屏幕时,这可能很有用
- 静态
- 动态
事件监听器
事件监听器可用于订阅为屏幕发出的各种事件。有关更多详细信息,请参阅 Screen
上的 listeners
属性。