跳到主要内容
版本:7.x

结合静态和动态 API

虽然静态 API 有许多优点,但它不适用于导航配置需要是动态的用例。因此,React Navigation 支持静态和动态 API 之间的互操作。

请记住,静态 API 提供的功能(例如自动链接配置和自动 TypeScript 类型)需要整个配置是静态的。如果部分配置是动态的,则需要手动处理这些部分。

您可能希望结合静态和动态 API 的方式有两种

静态根导航器,动态嵌套导航器

如果您想保持配置静态,但需要为特定导航器使用动态配置,这将非常有用。

让我们考虑以下示例

  • 您有一个根堆栈导航器,其中包含屏幕中的标签导航器。
  • 标签导航器是使用动态 API 定义的。

我们的静态配置如下所示

import { createNativeStackNavigator } from '@react-navigation/native-stack';

const RootStack = createNativeStackNavigator({
screens: {
Home: {
screen: HomeScreen,
},
Feed: {
screen: FeedScreen,
linking: {
path: 'feed',
},
},
},
});

在这里,FeedScreen 是一个组件,它渲染一个标签导航器,并使用动态 API 定义

import { createBottomTabNavigator } from '@react-navigation/bottom-tabs';

const Tab = createBottomTabNavigator();

function FeedScreen() {
return (
<Tab.Navigator>
<Tab.Screen name="Latest" component={LatestScreen} />
<Tab.Screen name="Popular" component={PopularScreen} />
</Tab.Navigator>
);
}

此代码可以工作,但我们缺少 2 件事

  • 顶部标签导航器中屏幕的链接配置。
  • 顶部标签导航器中屏幕的 TypeScript 类型。

由于嵌套导航器是使用动态 API 定义的,因此我们需要手动处理这些。对于链接配置,我们可以在 Feed 屏幕的 linking 属性中定义屏幕

import { createNativeStackNavigator } from '@react-navigation/native-stack';

const RootStack = createNativeStackNavigator({
screens: {
Home: {
screen: HomeScreen,
},
Feed: {
screen: FeedScreen,
linking: {
path: 'feed',
screens: {
Latest: 'latest',
Popular: 'popular',
},
},
},
},
});

这里的 screens 属性与您使用动态 API 定义 linking 配置的方式相同。它可以包含任何嵌套导航器的配置。有关 API 的更多详细信息,请参阅配置链接

对于 TypeScript 类型,我们可以定义 FeedScreen 组件的类型

import {
StaticScreenProps,
NavigatorScreenParams,
} from '@react-navigation/native';

type FeedParamList = {
Latest: undefined;
Popular: undefined;
};

type Props = StaticScreenProps<NavigatorScreenParams<FeedParamList>>;

function FeedScreen(_: Props) {
// ...
}

在上面的代码片段中

  1. 我们首先为导航器中的屏幕定义参数列表类型,该类型为每个屏幕定义参数
  2. 然后,我们使用 NavigatorScreenParams 类型来获取路由 params 的类型,这将包括嵌套屏幕的类型
  3. 最后,我们将 params 的类型与 StaticScreenProps 一起使用,以定义屏幕组件的类型

这是基于我们如何使用动态 API 为带有嵌套导航器的屏幕定义类型。请参阅类型检查嵌套导航器中的屏幕和参数

动态根导航器,静态嵌套导航器

如果您已经有动态配置,但想迁移到静态 API,这将非常有用。这样,您可以一次迁移一个导航器。

让我们考虑以下示例

  • 您有一个根堆栈导航器,其中包含屏幕中的标签导航器。
  • 根堆栈导航器是使用动态 API 定义的。

我们的动态配置如下所示

import { createNativeStackNavigator } from '@react-navigation/native-stack';

const RootStack = createNativeStackNavigator();

function RootStackScreen() {
return (
<RootStack.Navigator>
<RootStack.Screen name="Home" component={HomeScreen} />
<RootStack.Screen name="Feed" component={FeedScreen} />
</RootStack.Navigator>
);
}

在这里,FeedScreen 是一个组件,它渲染一个标签导航器,并使用静态 API 定义

import { createBottomTabNavigator } from '@react-navigation/bottom-tabs';

const FeedTabs = createBottomTabNavigator({
screens: {
Latest: {
screen: LatestScreen,
},
Popular: {
screen: PopularScreen,
},
},
});

要将 FeedTabs 导航器用于 Feed 屏幕,我们需要使用 createComponentForStaticNavigation 函数

import { createComponentForStaticNavigation } from '@react-navigation/native';

const FeedScreen = createComponentForStaticNavigation(FeedTabs, 'Feed');

此外,我们可以为 FeedTabs 导航器生成 TypeScript 类型,并在 RootStack 的类型中使用它,而无需手动编写它们

import {
StaticParamList,
NavigatorScreenParams,
} from '@react-navigation/native';

type FeedTabsParamList = StaticParamList<typeof FeedTabs>;

type RootStackParamList = {
Home: undefined;
Feed: NavigatorScreenParams<FeedTabsParamList>;
};

同样,我们可以为 FeedTabs 导航器生成链接配置,并在传递给 NavigationContainer 的链接配置中使用它

import { createPathConfigForStaticNavigation } from '@react-navigation/native';

const feedScreens = createPathConfigForStaticNavigation(FeedTabs);

const linking = {
prefixes: ['https://mychat.com', 'mychat://'],
config: {
screens: {
Home: '',
Feed: {
path: 'feed',
screens: feedScreens,
},
},
},
};

这将根据 FeedTabs 导航器的配置为 Feed 屏幕生成链接配置。