Вложенные навигаторы
Реальные приложения комбинируют несколько навигаторов: стек внутри таба, drawer со стеком, модалки поверх всего.
Структура
RootStack
├── Tabs (BottomTab)
│ ├── Feed (Stack)
│ │ ├── FeedList
│ │ └── PostDetails
│ ├── Search
│ └── Profile (Stack)
│ ├── ProfileView
│ └── Settings
├── Modal
└── Auth (Stack)
Реализация
const RootStack = createNativeStackNavigator<RootStackParamList>();
const Tab = createBottomTabNavigator<TabParamList>();
const FeedStack = createNativeStackNavigator<FeedStackParamList>();
function FeedNavigator() {
return (
<FeedStack.Navigator>
<FeedStack.Screen name="FeedList" component={FeedListScreen} />
<FeedStack.Screen name="PostDetails" component={PostDetailsScreen} />
</FeedStack.Navigator>
);
}
function TabNavigator() {
return (
<Tab.Navigator>
<Tab.Screen name="Feed" component={FeedNavigator} />
<Tab.Screen name="Search" component={SearchScreen} />
<Tab.Screen name="Profile" component={ProfileScreen} />
</Tab.Navigator>
);
}
export default function RootNavigator() {
return (
<RootStack.Navigator screenOptions={{ headerShown: false }}>
<RootStack.Screen name="Tabs" component={TabNavigator} />
<RootStack.Screen name="Modal" component={ModalScreen} options={{ presentation: 'modal' }} />
</RootStack.Navigator>
);
}
Типизация
export type FeedStackParamList = {
FeedList: undefined;
PostDetails: { id: number };
};
export type TabParamList = {
Feed: NavigatorScreenParams<FeedStackParamList>;
Search: undefined;
Profile: undefined;
};
export type RootStackParamList = {
Tabs: NavigatorScreenParams<TabParamList>;
Modal: undefined;
};
NavigatorScreenParams позволяет передавать параметры вложенных экранов.
Навигация во вложенный
Из RootStack перейти на PostDetails внутри FeedStack:
navigation.navigate('Tabs', {
screen: 'Feed',
params: {
screen: 'PostDetails',
params: { id: 5 },
},
});
useNavigation с типами
На экране внутри стека:
const navigation = useNavigation<NativeStackNavigationProp<FeedStackParamList>>();
navigation.navigate('PostDetails', { id: 5 });
На экране в корне:
const navigation = useNavigation<NativeStackNavigationProp<RootStackParamList>>();
navigation.navigate('Modal');
getParent
Из вложенного выйти на родительский:
navigation.getParent()?.navigate('Modal');
Или с типами:
const parent = navigation.getParent<NativeStackNavigationProp<RootStackParamList>>();
parent?.navigate('Modal');
Модалки
Модалка на уровне корневого стека:
<RootStack.Screen
name="ImagePreview"
component={ImagePreview}
options={{
presentation: 'transparentModal',
animation: 'fade',
headerShown: false,
}}
/>
Итоги
- Реальные приложения — комбинация навигаторов
NavigatorScreenParamsдля вложенныхnavigate('Tabs', { screen: 'Feed', params: {...} })getParentдля родителя- Модалки на корневом стеке