Search

Navigation 관례

Tags
Frontend
Date
2024/10/15

1. 개요

이번 포스팅에서는 Navigation 기능을 구현할 때 고려해야 할 흐름과 관례에 대해 살펴보겠습니다. 특히 코드를 작성할 때 자주 마주하게 되는 핵심 개념들을 짚고 넘어가보도록 하겠습니다.

2. 요구 사항 분석

상황을 가정해보겠습니다. 실제 제가 개발하고 있는 앱의 요구 사항 중 하나이기도 합니다 :)
온보딩 페이지를 만들어야 합니다. 1. 온보딩 페이지는 닉네임 입력, 아이디 입력, 생년월일 입력으로 구분됩니다. 2. 온보딩 페이지는 로그인 화면으로 부터 이동될 수 있습니다. (회원 가입이 안되어있을 때) 3. 아이디 입력과 생년월입 입력 페이지에는 이전에 입력했던 닉네임이 포함됩니다.
JSON
복사
이 요구 사항을 바탕으로, 온보딩 네비게이션 흐름을 설계하고 개발해보겠습니다.

3. 그룹 별로 패키지 화

네비게이션에는 여러 종류가 존재합니다. 예를 들어, 화면이 차례대로 쌓이는 Stack 네비게이션, 하단에 탭 메뉴가 있는 Tab 네비게이션, 그리고 좌측에서 열리는 Drawer 네비게이션이 있습니다. 각각의 네비게이션 방식은 앱의 흐름에 맞게 선택하여 사용해야 합니다.
 그렇다면 우리의 요구사항인 온보딩은 어느 형태의 네비게이션에 속할까요?
온보딩 과정은 사용자가 화면을 순차적으로 이동하는 스택(Stack) 네비게이션 구조에 속합니다. 닉네임 입력 → 아이디 입력 → 생년월일 입력 화면이 차례대로 쌓이면서 진행되기 때문입니다.

4. 네비게이션 경로를 상수로 관리하기

네비게이션 경로를 명확하고 일관성 있게 관리하기 위해 경로를 상수로 정의하는 것이 좋습니다. 이렇게 하면 오타나 중복을 방지할 수 있고, 경로 관리가 더 편리해집니다.
navigations.ts
const onboardingNavigations = { NICKNAME: 'Nickname', ID: 'ID', BIRTHDAY: 'Birthday', } as const; export { onboardingNavigations }
TypeScript
복사
이렇게 상수로 관리하면, 여러 화면에서 동일한 네비게이션 경로를 사용할 때 일관성을 유지할 수 있습니다.

5. Navigator 작성하기

이제 본격적으로 Navigator를 작성해보겠습니다. Navigator는 앱의 네비게이션 구조를 결정하는 핵심적인 역할을 합니다.

5-1. ParamList 생성

ParamList는 네비게이션 경로와 그 경로에 전달될 파라미터 타입을 정의합니다. 이를 통해 Type Checking를 할 수 있습니다.
Type Checking은 간단히 말해 코드에서 변수나 함수의 데이터 타입을 미리 검사하여, 잘못된 타입으로 인한 오류를 방지하는 과정입니다. React Navigation에서는 TypeScript의 타입 검사를 통해 각 화면으로 전달되는 파라미터의 타입을 명확히 지정하고, 네비게이션 경로에 대한 타입 안전성을 확보할 수 있습니다.
export type OnboardingStackParamList = { [onboardingNavigations.NICKNAME]: undefined; [onboardingNavigations.ID]: {nickname: string}; [onboardingNavigations.BIRTHDAY]: {nickname: string}; }
TypeScript
복사
위 코드에서, nickname은 아이디 입력 및 생일 입력 화면으로 전달되는 파라미터입니다.

5-2. Stack Navigator 생성

createStackNavigator를 사용하여 온보딩 화면을 위한 Stack Navigator를 생성합니다. 이는 화면이 쌓이는 스택을 만드는 함수입니다.
const Stack = createStackNavigator<OnboardingStackParamList>()
TypeScript
복사

5-3. 구현체 작성

이제 OnboardingStackNavigator 컴포넌트를 구현해보겠습니다. 각 스크린을 네비게이션 경로에 맞춰 연결하고, 필요에 따라 화면의 옵션을 설정합니다.
import React from 'react'; import { createStackNavigator } from '@react-navigation/stack'; import { onboardingNavigations } from '@/constants'; import OnboardingNicknameScreen from '@/screens/onboarding/OnboardingNicknameScreen'; import OnboardingIdScreen from '@/screens/onboarding/OnboardingIdScreen'; import OnboardingBirthdayScreen from '@/screens/onboarding/OnboardingBirthdayScreen'; export type OnboardingStackParamList = { [onboardingNavigations.NICKNAME]: undefined; [onboardingNavigations.ID]: { nickname: string }; [onboardingNavigations.BIRTHDAY]: { nickname: string }; }; const Stack = createStackNavigator<OnboardingStackParamList>(); function OnboardingStackNavigator() { return ( <Stack.Navigator> <Stack.Screen name={onboardingNavigations.NICKNAME} component={OnboardingNicknameScreen} options={{ headerShown: false, headerTitle: '' }} /> <Stack.Screen name={onboardingNavigations.ID} component={OnboardingIdScreen} options={{ headerTitle: '아이디 입력', headerBackTitleVisible: false }} /> <Stack.Screen name={onboardingNavigations.BIRTHDAY} component={OnboardingBirthdayScreen} options={{ headerTitle: '생일 입력' }} /> </Stack.Navigator> ); } export default OnboardingStackNavigator;
TypeScript
복사

Reference