Навигация в компонентах
Компоненты часто нужны навигацию для переходов. Разберём базовые приёмы.
useNavigation
Хук для доступа к навигации в любом компоненте внутри навигатора:
import { useNavigation } from '@react-navigation/native';
function BackButton() {
const navigation = useNavigation();
return (
<Pressable onPress={() => navigation.goBack()}>
<Text>Назад</Text>
</Pressable>
);
}
Не требует передачи navigation через пропсы.
useRoute
Параметры текущего экрана:
import { useRoute } from '@react-navigation/native';
function Details() {
const route = useRoute();
const { id } = route.params as { id: number };
return <Text>ID: {id}</Text>;
}
Navigate между экранами
navigation.navigate('Details', { id: 5 });
Если экран уже в стеке — вернётся на него. Если нет — добавит.
Push
navigation.push('Details', { id: 5 });
Всегда добавляет новый экран, даже если такой же уже есть.
Replace
navigation.replace('Login');
Заменяет текущий экран. Назад вернуться нельзя.
Go back
navigation.goBack();
navigation.pop(); // то же
navigation.popToTop(); // вернуться к первому
Параметры с типами
type RootStackParamList = {
Home: undefined;
Details: { id: number; title?: string };
Profile: { userId: string };
};
type NavigationProp = NativeStackNavigationProp<RootStackParamList>;
function DetailsScreen() {
const route = useRoute<RouteProp<RootStackParamList, 'Details'>>();
const navigation = useNavigation<NavigationProp>();
const { id, title } = route.params;
return (
<Pressable onPress={() => navigation.navigate('Profile', { userId: 'abc' })}>
<Text>{title ?? `Детали ${id}`}</Text>
</Pressable>
);
}
Хедер с кнопкой
function Screen() {
const navigation = useNavigation();
useLayoutEffect(() => {
navigation.setOptions({
headerRight: () => (
<Pressable onPress={() => navigation.navigate('Settings')}>
<Ionicons name="settings" size={24} />
</Pressable>
),
});
}, [navigation]);
return <View />;
}
useFocusEffect
Эффект при фокусе экрана:
import { useFocusEffect } from '@react-navigation/native';
import { useCallback } from 'react';
function Screen() {
useFocusEffect(
useCallback(() => {
console.log('экран в фокусе');
return () => console.log('экран потерял фокус');
}, [])
);
return <View />;
}
Используется для обновления данных при возврате на экран.
If focused
import { useIsFocused } from '@react-navigation/native';
function Screen() {
const isFocused = useIsFocused();
return isFocused ? <VideoPlayer /> : <VideoPaused />;
}
Before remove
Предотвратить уход с экрана:
useEffect(() => {
const unsubscribe = navigation.addListener('beforeRemove', (e) => {
if (!hasUnsavedChanges) return;
e.preventDefault();
Alert.alert('Уйти?', 'Изменения не сохранятся', [
{ text: 'Остаться', style: 'cancel' },
{ text: 'Уйти', onPress: () => navigation.dispatch(e.data.action) },
]);
});
return unsubscribe;
}, [navigation, hasUnsavedChanges]);
Если ты уже знаешь React
В вебе — useNavigate из React Router. В React Native — useNavigation из React Navigation. Логика похожа, API отличается.
Итоги
useNavigationв компонентахuseRouteдля параметровnavigate,push,replace,goBackuseLayoutEffectдля хедераuseFocusEffectдля обновления при фокусеbeforeRemoveдля подтверждения выхода