Введение
Если вы когда-нибудь пользовались приложениями вроде Gmail или Spotify, вы наверняка заметили, как боковая панель (также известная как "бургер-меню", но не потому что мы любим перекусывать) помогает организовать доступ к дополнительным разделам. В отличие от табов, которые всегда на экране, боковая панель появляется только при необходимости, что делает её достаточно удобной для продвинутой навигации.
Когда использовать Drawer Navigation?
Боковая панель идеально подходит для следующих задач:
- Скрытие редко используемых разделов.
- Управление настройками, профилями.
- Создание навигации для сложных приложений с большим количеством контента.
Установка и настройка Drawer Navigation
Для работы с Drawer Navigation нам понадобится установить дополнительные пакеты. Запустите следующую команду:
npm install @react-navigation/drawer react-native-gesture-handler react-native-reanimated react-native-screens react-native-safe-area-context react-native-vector-icons
Обратите внимание, что здесь мы включаем несколько библиотек, таких как react-native-gesture-handler и react-native-reanimated, которые необходимы для обработки жестов и анимации в навигации.
После установки не забудьте перезапустить Metro Bundler и перезагрузить эмулятор.
Теперь создадим наш Drawer Navigator. Для этого потребуется модуль createDrawerNavigator из библиотеки @react-navigation/drawer. Начнём настройку:
import React from 'react';
import { NavigationContainer } from '@react-navigation/native';
import { createDrawerNavigator } from '@react-navigation/drawer';
import HomeScreen from './screens/HomeScreen';
import ProfileScreen from './screens/ProfileScreen';
const Drawer = createDrawerNavigator();
const App = () => {
return (
<NavigationContainer>
<Drawer.Navigator initialRouteName="Home">
<Drawer.Screen name="Home" component={HomeScreen} />
<Drawer.Screen name="Profile" component={ProfileScreen} />
</Drawer.Navigator>
</NavigationContainer>
);
};
export default App;
В этом коде:
- Компонент
Drawer.Navigatorопределяет контейнер для боковой панели. Drawer.Screenопределяет каждый экран, который будет отображаться внутри нашего дровера.NavigationContainerоборачивает всю навигацию, как и раньше.
Типизация Drawer Navigation с TypeScript
Мы знаем, как важна строгая типизация для предотвращения ошибок (и здоровья разработчиков). Давайте добавим типы к нашему Drawer Navigator.
Определение типов маршрутов
Сначала создадим интерфейс для маршрутов:
export type DrawerParamList = {
Home: undefined; // Экран Home не принимает параметры
Profile: { userId: string }; // Экран Profile принимает параметр userId
};
Затем передадим этот интерфейс в наш Drawer.Navigator:
import { createDrawerNavigator } from '@react-navigation/drawer';
import type { DrawerParamList } from './types';
const Drawer = createDrawerNavigator<DrawerParamList>();
Теперь, если вы попробуете добавить экран с неправильным набором параметров, TypeScript вас предупредит!
Создание и настройка компонентов Drawer
Для демонстрации мы добавим два экрана: HomeScreen и ProfileScreen.
// screens/HomeScreen.tsx
import React from 'react';
import { View, Text, StyleSheet } from 'react-native';
const HomeScreen = () => (
<View style={styles.container}>
<Text>Welcome to the Home Screen!</Text>
</View>
);
const styles = StyleSheet.create({
container: {
flex: 1,
justifyContent: 'center',
alignItems: 'center',
},
});
export default HomeScreen;
// screens/ProfileScreen.tsx
import React from 'react';
import { View, Text, StyleSheet } from 'react-native';
type ProfileScreenProps = {
route: { params: { userId: string } };
};
const ProfileScreen = ({ route }: ProfileScreenProps) => {
const { userId } = route.params;
return (
<View style={styles.container}>
<Text>Welcome, user {userId}!</Text>
</View>
);
};
const styles = StyleSheet.create({
container: {
flex: 1,
justifyContent: 'center',
alignItems: 'center',
},
});
export default ProfileScreen;
Мы также добавили типизацию параметров экрана ProfileScreen, чтобы соответствовать нашему интерфейсу DrawerParamList.
Кастомизация боковой панели
Базовые настройки — это хорошо, но кастомизация превращает приложение в произведение искусства.
Настройка стилей Drawer Navigation
Мы можем настроить стили, добавив пропс drawerStyle:
<Drawer.Navigator
screenOptions={{
drawerStyle: {
backgroundColor: '#e6f7ff', // Цвет фона
width: 240, // Ширина панели
},
headerStyle: {
backgroundColor: '#4caf50', // Цвет заголовка
},
headerTintColor: '#fff', // Цвет текста заголовка
}}
>
Добавление кастомного контента
Для полного контроля над боковой панелью мы можем использовать drawerContent:
<Drawer.Navigator
drawerContent={(props) => <CustomDrawerContent {...props} />}
>
А теперь создадим кастомный компонент панели:
import React from 'react';
import { DrawerContentScrollView, DrawerItemList, DrawerItem } from '@react-navigation/drawer';
import { View, Text, StyleSheet } from 'react-native';
const CustomDrawerContent = (props: any) => (
<DrawerContentScrollView {...props}>
<View style={styles.header}>
<Text style={styles.headerText}>My App</Text>
</View>
<DrawerItemList {...props} />
<DrawerItem label="Help" onPress={() => console.log('Navigate to Help')} />
</DrawerContentScrollView>
);
const styles = StyleSheet.create({
header: {
padding: 20,
backgroundColor: '#4caf50',
},
headerText: {
color: '#fff',
fontSize: 18,
fontWeight: 'bold',
},
});
export default CustomDrawerContent;
Типичные ошибки и сложные моменты
1. Ошибка с библиотеками жестов
Некоторые разработчики забывают связать библиотеку react-native-gesture-handler. Чтобы исправить это, импортируйте её в index.js:
import 'react-native-gesture-handler';
2. Проблемы с типизацией
Обратите внимание, что для параметров маршрутов типы нужно указывать как в Drawer.Navigator, так и в компонентах экранов.
3. Кастомный контент ломает навигацию
Если забыть правильно передать пропс props в DrawerContentScrollView, навигация может перестать работать.
ПЕРЕЙДИТЕ В ПОЛНУЮ ВЕРСИЮ