Урок 07

Параметры и типизация

Правильная типизация параметров — основа безопасной навигации.

Определение типов

// navigation/types.ts
export type RootStackParamList = {
    Home: undefined;
    Details: { id: number; title?: string };
    Profile: { userId: string };
    Settings: undefined;
};

undefined — экран без параметров.

createNativeStackNavigator с типами

const Stack = createNativeStackNavigator<RootStackParamList>();

Теперь name проверяется. Опечатка — ошибка.

Типы для навигации

import type { NativeStackNavigationProp, NativeStackScreenProps } from '@react-navigation/native-stack';
import type { RouteProp } from '@react-navigation/native';

// для useNavigation
const navigation = useNavigation<NativeStackNavigationProp<RootStackParamList>>();

// для props экрана
type DetailsProps = NativeStackScreenProps<RootStackParamList, 'Details'>;

function DetailsScreen({ navigation, route }: DetailsProps) {
    const { id } = route.params;
}

NativeStackScreenProps<ParamList, 'ScreenName'> — самый удобный способ.

useRoute с типами

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

const route = useRoute<RouteProp<RootStackParamList, 'Details'>>();
const { id, title } = route.params;

Отправка параметров

navigation.navigate('Details', { id: 5 });
navigation.navigate('Details', { id: 5, title: 'Пост' });

TypeScript проверяет:

navigation.navigate('Details', {});        // ошибка — нет id
navigation.navigate('Details', { id: '5' }); // ошибка — id должен быть number

Необязательные параметры

type RootStackParamList = {
    Details: { id: number; title?: string };
};

navigation.navigate('Details', { id: 5 }); // ок
navigation.navigate('Details', { id: 5, title: 'X' }); // ок

Обновление параметров

navigation.setParams({ title: 'Новое' });

Обновляет параметры текущего экрана.

Значения по умолчанию

function DetailsScreen({ route }: DetailsProps) {
    const { id, title = `Пост ${id}` } = route.params;
    return <Text>{title}</Text>;
}

Параметры с объектами

type RootStackParamList = {
    Editor: { post: Post; mode: 'create' | 'edit' };
};

navigation.navigate('Editor', { post, mode: 'edit' });

Передача больших объектов — не рекомендуется. Лучше id и загрузка на месте.

Сериализация

Параметры должны быть сериализуемыми: строки, числа, массивы, простые объекты. Функции и Date — нельзя.

Правильно:

navigation.navigate('Details', { id: 5, timestamp: Date.now() });

Неправильно:

navigation.navigate('Details', { onClick: () => {} }); // ошибка

Параметры между вложенными

navigation.navigate('Tabs', {
    screen: 'Profile',
    params: { userId: 'abc' },
});

Итоги

  • RootStackParamList для всех экранов
  • NativeStackScreenProps<ParamList, 'Screen'> для props
  • useNavigation<NativeStackNavigationProp<ParamList>>() для хука
  • Параметры должны быть сериализуемыми
  • setParams для обновления текущего