Что такое Stack Navigation?
Stack Navigation — это способ организовать экраны в приложении в виде стэка. Представьте это как стопку карт: верхняя карта (экран) — это текущий видимый экран, а под ней — предыдущие экраны. Когда пользователь переходит на новый экран, он добавляется поверх стэка. При возврате назад верхний экран удаляется, и пользователь снова видит предыдущий экран.
Вот основной принцип: "push для перехода, pop для возврата". Это интуитивно понятно и широко используется в мобильных приложениях, особенно для навигации между страницами, связанных иерархически.
Подготовка к созданию Stack Navigator
На предыдущей лекции мы уже обсуждали установку React Navigation. Убедитесь, что у Вас установлены следующие пакеты:
npm install @react-navigation/native react-native-screens react-native-safe-area-context react-native-gesture-handler react-native-reanimated
npm install @react-navigation/stack
Если вы забыли установить что-то, сейчас самое время это сделать.
Импорт и настройка Stack Navigation
React Navigation предоставляет компонент createStackNavigator, с помощью которого мы можем создавать стэки экранов.
Начнем с импорта:
import React from 'react';
import { createStackNavigator } from '@react-navigation/stack';
import { NavigationContainer } from '@react-navigation/native';
import { HomeScreen } from './screens/HomeScreen'; // Наши экраны
import { DetailsScreen } from './screens/DetailsScreen';
Здесь мы импортируем createStackNavigator для создания стэка экранов и NavigationContainer для обёртки всего приложения.
Создание Stack Navigator
Создадим наш Stack Navigator и настроим экраны.
const Stack = createStackNavigator();
export const AppNavigator = () => {
return (
<NavigationContainer>
<Stack.Navigator>
<Stack.Screen name="Home" component={HomeScreen} />
<Stack.Screen name="Details" component={DetailsScreen} />
</Stack.Navigator>
</NavigationContainer>
);
};
Разбор кода
Stack.Navigator— контейнер для стэка экранов.Stack.Screen— каждый экран в стэке. Мы указываем имя экранаnameи компонент, который будет отображатьсяcomponent.NavigationContainer— оборачивает все навигационные компоненты и позволяет приложению использовать навигацию.
На этом этапе у нас есть базовая навигация с двумя экранами: HomeScreen и DetailsScreen.
Добавление экранов и их компонентов
Теперь создадим сами экраны. Пусть это будут два простых компонента:
HomeScreen.tsx
import React from 'react';
import { View, Text, Button } from 'react-native';
export const HomeScreen = ({ navigation }: { navigation: any }) => {
return (
<View style={{ flex: 1, justifyContent: 'center', alignItems: 'center' }}>
<Text>Добро пожаловать на Главную страницу!</Text>
<Button
title="Перейти к деталям"
onPress={() => navigation.navigate('Details', { itemId: 42 })}
/>
</View>
);
};
Код пояснения
navigation.navigate()— метод, который перемещает пользователя на другой экран. Здесь мы передаем имя экранаDetailsи параметры (в данном случаеitemId).
DetailsScreen.tsx
import React from 'react';
import { View, Text, Button } from 'react-native';
export const DetailsScreen = ({ route, navigation }: { route: any; navigation: any }) => {
const { itemId } = route.params;
return (
<View style={{ flex: 1, justifyContent: 'center', alignItems: 'center' }}>
<Text>Вы находитесь на странице деталей для Item ID: {itemId}</Text>
<Button title="Вернуться назад" onPress={() => navigation.goBack()} />
</View>
);
};
Код пояснения
route.params— объект, который содержит параметры, переданные при навигации.navigation.goBack()— метод, возвращающий на предыдущий экран в стэке.
Настройка заголовков и параметров навигации
Вы можете настроить заголовки экранов прямо в Stack.Screen. Например:
<Stack.Screen
name="Home"
component={HomeScreen}
options={{ title: 'Моя главная страница' }}
/>
Но более динамичным способом будет управление заголовком из самих компонентов. Например:
React.useLayoutEffect(() => {
navigation.setOptions({ title: `Детали для Item ID: ${itemId}` });
}, [navigation, itemId]);
Этот код задаёт заголовок на основе данных (например, itemId), переданных в параметры.
Типизация параметров навигации с TypeScript
Давайте добавим типизацию! Для этого мы создадим интерфейс типов стэка экранов:
import { RouteProp } from '@react-navigation/native';
import { StackNavigationProp } from '@react-navigation/stack';
type RootStackParamList = {
Home: undefined;
Details: { itemId: number };
};
// Типизация пропсов навигации
type DetailsScreenRouteProp = RouteProp<RootStackParamList, 'Details'>;
type DetailsScreenNavigationProp = StackNavigationProp<RootStackParamList, 'Details'>;
type Props = {
route: DetailsScreenRouteProp;
navigation: DetailsScreenNavigationProp;
};
Теперь обновим наш DetailsScreen с типизацией:
export const DetailsScreen = ({ route, navigation }: Props) => {
const { itemId } = route.params;
return (
<View style={{ flex: 1, justifyContent: 'center', alignItems: 'center' }}>
<Text>Вы находитесь на странице деталей для Item ID: {itemId}</Text>
<Button title="Вернуться назад" onPress={() => navigation.goBack()} />
</View>
);
};
Типичные ошибки и способы их избежать
Ошибка 1: "Cannot use navigation of undefined"
Это может произойти, если вы забыли обернуть приложение в NavigationContainer. Убедитесь, что всё внутри <NavigationContainer>.
Ошибка 2: "Параметры route.params — undefined"
Параметры могут быть не переданы. Обязательно проверяйте их наличие и типизируйте их в маршрутах для предотвращения ошибок.
Ошибка 3: Неуказанные зависимости в хуке useLayoutEffect
Если вы используете useLayoutEffect, например, для изменения заголовка, всегда добавляйте все зависимые переменные (например, itemId и navigation) в массив зависимостей.
Теперь вы подготовлены к успеху в организации Stack Navigation! Мы разобрались с её созданием, а также добавили базовую типизацию и убедились, что все работает корректно. В следующих лекциях мы продолжим улучшать навигацию с помощью других видов, таких как Bottom Tab Navigation!
ПЕРЕЙДИТЕ В ПОЛНУЮ ВЕРСИЮ