JavaRush /Курсы /Модуль 3: React /Типизация Tab Navigation и её компонентов — интерфейсы дл...

Типизация Tab Navigation и её компонентов — интерфейсы для каждого экрана

Модуль 3: React
22 уровень , 5 лекция
Открыта

Напоминание о Bottom Tab Navigation

Перед тем как углубиться в типизацию, давайте вспомним, как мы на прошлом занятии создали Bottom Tab Navigation. Вот простой пример:

import React from 'react';
import { createBottomTabNavigator } from '@react-navigation/bottom-tabs';
import HomeScreen from './HomeScreen';
import SettingsScreen from './SettingsScreen';

const Tab = createBottomTabNavigator();

const MyTabs = () => {
  return (
    <Tab.Navigator>
      <Tab.Screen name="Home" component={HomeScreen} />
      <Tab.Screen name="Settings" component={SettingsScreen} />
    </Tab.Navigator>
  );
};

export default MyTabs;

Мы создали навигатор Tab.Navigator с двумя экранами — Home и Settings. Всё просто, правда? Но попробуйте передать в SettingsScreen параметры, а затем их использовать. Без типизации вы будете гадать, какие данные должны быть переданы и что там будет внутри.

Создание интерфейса для типов параметров Tab Navigation

Теперь перейдём к типизации. Будем использовать интерфейс TypeScript для описания параметров, которые может принимать каждый экран.

Пример типизации параметров:

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

// Интерфейс для параметров экранов в Tab Navigator
interface TabParamList {
  Home: undefined; // Экран Home не принимает параметров
  Settings: { userId: string }; // Экран Settings принимает параметр userId
}
  • Home: мы указываем undefined, так как для этого экрана параметров не требуется.
  • Settings: экран принимает параметр userId, который является строкой. Теперь ваш код чётко знает, какие параметры должны быть переданы.

Применение интерфейса в Tab Navigator

Типизация в createBottomTabNavigator выполняется с помощью дженерика (generic). Попробуем:

import React from 'react';
import { createBottomTabNavigator } from '@react-navigation/bottom-tabs';
import HomeScreen from './HomeScreen';
import SettingsScreen from './SettingsScreen';

// Определяем TabParamList
interface TabParamList {
  Home: undefined;
  Settings: { userId: string };
}

// Создаём Tab Navigator с типами
const Tab = createBottomTabNavigator<TabParamList>();

const MyTabs = () => {
  return (
    <Tab.Navigator>
      <Tab.Screen name="Home" component={HomeScreen} />
      <Tab.Screen
        name="Settings"
        component={SettingsScreen}
        initialParams={{ userId: 'default_user' }} // Указываем начальные параметры
      />
    </Tab.Navigator>
  );
};

export default MyTabs;

Отлично! Теперь createBottomTabNavigator знает, что все экраны должны соответствовать интерфейсу TabParamList.

Типизация параметров экрана с useRoute

Теперь давайте типизируем параметры в самих экранах. Используем хук useRoute, чтобы получить данные.

Пример: использование параметров в HomeScreen

import React from 'react';
import { View, Text } from 'react-native';
import { useRoute, RouteProp } from '@react-navigation/native';

// Определяем типы маршрута для Home
type HomeRouteProp = RouteProp<TabParamList, 'Settings'>;

const SettingsScreen = () => {
  const route = useRoute<HomeRouteProp>();

  return (
    <View>
      <Text>User ID: {route.params.userId}</Text>
    </View>
  );
};

export default SettingsScreen;

Разбираем, что здесь происходит:

  1. RouteProp: этот тип описывает маршрут для конкретного экрана и берёт данные из TabParamList.
  2. useRoute<HomeRouteProp>: мы указываем конкретно для Settings, что он ожидает параметр userId. Теперь, если вы забудете передать userId при переходе на этот экран, TypeScript предупредит об этом.

Типизация параметров для навигации с useNavigation

А как быть, если вы хотите программно перемещаться между экранами? Для этого есть хук useNavigation. Давайте добавим типизацию и сюда.

import { useNavigation } from '@react-navigation/native';
import { BottomTabNavigationProp } from '@react-navigation/bottom-tabs';

// Определяем тип навигатора
type SettingsScreenNavigationProp = BottomTabNavigationProp<TabParamList, 'Settings'>;

const HomeScreen = () => {
  const navigation = useNavigation<SettingsScreenNavigationProp>();

  const goToSettings = () => {
    navigation.navigate('Settings', { userId: '12345' });
  };

  return (
    <View>
      <Button title="Go to Settings" onPress={goToSettings} />
    </View>
  );
};

export default HomeScreen;

Здесь мы типизировали навигацию для Settings, явно указав, что он требует параметр userId. Теперь TypeScript не даст нам случайно передать что-то, что не соответствует типу.

Часто задаваемые вопросы и типичные ошибки

Почему нельзя просто использовать any?

Использование any разрушает всю суть TypeScript. Вы лишаетесь проверки типов, что может привести к ошибкам, которые обнаруживаются только на этапе выполнения. Это как ездить на машине без тормозов: возможно, вы не упадёте с обрыва, но шансы есть.

А что делать, если экран не принимает параметры?

Если экран не принимает параметры, всегда указывайте undefined в интерфейсе. Например:

Home: undefined;

Как обработать опциональные параметры?

Для опциональных параметров используйте тип ?:

Settings: { userId?: string };
2
Задача
Модуль 3: React, 22 уровень, 5 лекция
Недоступна
Создание типизированного Tab Navigator
Создание типизированного Tab Navigator
Комментарии
ЧТОБЫ ПОСМОТРЕТЬ ВСЕ КОММЕНТАРИИ ИЛИ ОСТАВИТЬ КОММЕНТАРИЙ,
ПЕРЕЙДИТЕ В ПОЛНУЮ ВЕРСИЮ