navigation과 route 타입 설정하기

Tags
 
 

최종 정리

[0] 타입 정의

import { StackScreenProps } from '@react-navigation/stack'; export type fadeEffectProp = { current: { progress: any } }; // route.params로 전달될 속성값들을 명시한다. export type RootLoginStackParamList = { Login: undefined; SignUp: { testId: number }; }; // 스크린 컴포넌트가 전달받을 navigation, route 프롭을 정의한다. export type LoginProps = StackScreenProps<RootLoginStackParamList, 'Login'>; export type SignUpProps = StackScreenProps<RootLoginRootLoginStackParamListStack, 'SignUp'>;

[1] 네비게이터 생성 시 타입 전달

... import { createStackNavigator } from '@react-navigation/stack'; import { RootLoginStack } from './types'; ... const Stack = createStackNavigator<RootLoginStack>(); export default function LoginStack() { ... return ( <RecoilRoot> <Stack.Navigator> <Stack.Screen name="Login" component={LoginScreen} /> <Stack.Screen name="SignUp" component={SignUpScreen} /> </Stack.Navigator> </RecoilRoot> ); }

[2] 개별 스크린 사용 예시

... import { SignUpProps } from '@navigators/LoginStack/types'; ... export default function SignUpScreen({ navigation, route, }: SignUpProps): ReactElement { const onPress = () => navigation.navigate('Login'); return ( <SafeAreaView style={styles.container}> <SignUp onPress={onPress} text={`${route.params.testId}번 입니다.`} /> </SafeAreaView> ); }

[3] 컴포넌트에서 useNavigation으로 사용하고 싶은 경우

  • navigation과 route의 타입을 따로 설정하고 싶지 않아서, 한번에 설정할 수 있는 StackScreenProps로 타입을 정의한 경우
    • useNavigation() 훅을 사용하려면 navigation 타입만 전달해야함
    • 아래의 방법으로 해결 가능
const { navigate } = useNavigation< DiagnosisStackScreenProps<'DiagnosisDispensing'>['navigation'] >();
 
 

문서 번역

[1] 화면별 파라미터 타입 설정하기

하나의 화면 타입 지정 예시

  • 네비게이터에 속한 Profile 페이지가 userId 파라미터를 받는 경우
type RootStackParamList = { Profile: { userId: string }; };

여러 화면 타입 지정 예시

Home, Profile, Feed 3개의 화면이 하나의 스택 네비게이터에 속해있는 경우를 예로 듦.
type RootStackParamList = { Home: undefined; Profile: { userId: string }; Feed: { sort: 'latest' | 'top' } | undefined; };

[2] 네비게이터에 타입 명시

화면별 파라미터 타입을 설정했으면, 이제 네비게이터가 이를 사용하도록 명시 해줘야함.
createXNavigator 함수에 제네릭으로 타입을 명시하면 됨.

네비게이터 생성 시 제네릭으로 타입 전달

import { createStackNavigator } from '@react-navigation/stack'; const RootStack = createStackNavigator<RootStackParamList>();

타입 적용된 네비게이터

네비게이터와 스크린 컴포넌트들에 대해 타입 체킹, 프롭에 대한 intelliSense 제공됨.
// 이제 화면별 파라미터 타입설정이 완료됐으므로 그냥 쓰면 됨. <RootStack.Navigator initialRouteName="Home"> <RootStack.Screen name="Home" component={Home} /> <RootStack.Screen name="Profile" component={Profile} initialParams={{ userId: user.id }} /> <RootStack.Screen name="Feed" component={Feed} /> </RootStack.Navigator>
 

[3] 화면별 navigation 프롭 참조하기

먼저 대응되는 타입을 import 해야함.
StackNavigation을 기준으로 예를 들면 @react-navigation/stack에서 StackNavigationProp 임포트

navigation 프롭은 2개의 제네릭을 받는다.

  • 화면의 파라미터 타입
  • 화면의 이름
    • setParam 시 현재 화면에 맞는 프롬 타입인지 검사해야하므로 필요함.
import { StackNavigationProp } from '@react-navigation/stack'; type ProfileScreenNavigationProp = StackNavigationProp< RootStackParamList, 'Profile' >; type Props = { navigation: ProfileScreenNavigationProp; };

네비게이터별 navigation prop 정리

  • import {StackNavigationProp} from '@react-navigation/stack';
  • import {DrawerNavigationProp} from '@react-navigation/drawer'
  • import {BottomTabNavigationProp} from '@react-navigation/bottom-tabs'

[4] 화면별 route 프롭 참조하기

route 프롭을 annotate하려면 @react-navigation/native로부터 RouteProp type을 임포트 해야함.
이는 route object의 타입 체크를 할 수 있게 함.
  • route.params
import { RouteProp } from '@react-navigation/native'; type ProfileScreenRouteProp = RouteProp<RootStackParamList, 'Profile'>; type Props = { route: ProfileScreenRouteProp; };

RouteProp 임포트 하는법 정리

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

[5] 요약

5-1. navigation과 route prop을 각각 임포트하여 최종 prop 만들기

💡
타입들은 별도의 파일인 types.tsx에 빼두어 중복으로 선언하지 말고 임포트해서 쓰자.
import { RouteProp } from '@react-navigation/native'; import { StackNavigationProp } from '@react-navigation/stack'; type RootStackParamList = { Home: undefined; Profile: { userId: string }; Feed: { sort: 'latest' | 'top' } | undefined; }; // 해당 스크린의 route 프롭 type ProfileScreenRouteProp = RouteProp<RootStackParamList, 'Profile'>; // 해당 스크린의 navigation 프롭 type ProfileScreenNavigationProp = StackNavigationProp< RootStackParamList, 'Profile' >; // 화면의 최종 프롭 설정 type Props = { route: ProfileScreenRouteProp; navigation: ProfileScreenNavigationProp; };

[6] 제네릭으로 navigaion, route prop 한번에 만들기

import { StackScreenProps } from '@react-navigation/stack'; type RootStackParamList = { Home: undefined; Profile: { userId: string }; Feed: { sort: 'latest' | 'top' } | undefined; }; // navigation과 route 프롭이 한번에 설정되나? type Props = StackScreenProps<RootStackParamList, 'Profile'>;

화면별 ScreenProps 정리

  • import { StackScreenProps } from '@react-navigation/stack';
  • import { DrawerScreenProps } from '@react-navigation/drawer';
  • import { BottomTabScreenProps } from '@react-navigation/bottom-tabs';
  • import { MaterialTopTabScreenProps } from '@react-navigation/material-top-tabs';

사용 예시

  • 함수형
function ProfileScreen({ route, navigation }: Props) { // ... }
  • 클래스형
class ProfileScreen extends React.Component<Props> { render() { // ... } }