Stack Navigator — 스택 원리(LIFO)에 따라 모바일 앱 화면을 관리하기 위한 React Navigation 라이브러리의 컴포넌트입니다. 각각의 새 화면은 이전 화면 위에 배치되며, «뒤로» 버튼은 상단 화면을 제거하고 사용자를 이전 화면으로 되돌립니다. 네비게이션 아키텍처에 대한 자세한 내용은 React Navigation 공식 문서를 참조하세요.
핵심 포인트
Stack Navigator — 화면의 스택 모델을 구현하는 React Navigation 라이브러리의 기본 네비게이터 중 하나입니다. 모바일 사용자에게 익숙한 네비게이션을 제공합니다. 새 화면을 열면 오른쪽으로 슬라이드 애니메이션이 함께 제공되며, «뒤로» 버튼이나 스와이프 제스처로 이전 화면으로 돌아갑니다. Stack Navigator는 iOS와 Android를 지원하며, 최대 성능을 위해 플랫폼의 네이티브 컴포넌트를 사용합니다.
React Navigation은 React Native에서 가장 인기 있는 네비게이션 라이브러리로, 프로젝트의 85%에 설치되어 있습니다(npm 데이터, 2026년 기준). Stack Navigator는 핵심의 일부이며 두 가지 구현으로 제공됩니다: createNativeStackNavigator(네이티브, 권장) 및 createStackNavigator(JavaScript, 복잡한 사용자 정의 애니메이션용). 네이티브 버전은 React Navigation v5에서 등장하여 v6+에서 표준이 되었습니다.
Stack Navigator의 주요 장점 — iOS 및 Android 사용자에게 친숙한 자연스러운 동작입니다. iOS에서는 스택이 UINavigationController로 시각적으로 표현되고, Android에서는 슬라이드 애니메이션이 있는 FragmentManager로 표현됩니다. 개발자가 수동으로 스택 로직을 구현할 필요가 없습니다. 네비게이터가 화면 상태, 백 스택 및 애니메이션을 자동으로 관리합니다.
스택 네비게이션은 LIFO(Last In, First Out) 원리에 기반합니다. 사용자가 새 화면을 열면 네비게이터가 스택 맨 위에 배치합니다. «뒤로»를 누르면 상단 화면이 제거되고 사용자가 이전 화면을 봅니다. 스택은 원하는 수의 화면을 포함할 수 있습니다. 유일한 제한은 기기 메모리입니다.
스택의 각 화면은 상태를 유지합니다. 이전 화면으로 돌아가면 해당 상태가 자동으로 복원됩니다. 이는 스택을 다른 네비게이션 유형(Tab, Drawer)과 구분하며, 다른 유형에서는 화면이 다시 생성될 수 있습니다. React Navigation은 자체 네비게이션 컨텍스트 메커니즘을 통해 상태를 관리합니다.
| 작업 | 결과 | 예시 |
|---|---|---|
| navigate | 화면을 스택 맨 위에 배치 | navigation.navigate('Profile') |
| goBack | 스택에서 상단 화면 제거 | navigation.goBack() |
| push | 강제로 새 화면 추가 | navigation.push('Profile') |
| popToTop | 루트 화면으로 돌아가기 | navigation.popToTop() |
| reset | 전체 스택을 새 세트로 교체 | navigation.reset({ index: 0, routes: [...] }) |
iOS에서 Stack Navigator는 왼쪽 가장자리에서 스와이프하여 뒤로 가는 제스처를 지원합니다. 이는 사용자가 기대하는 표준 iOS 동작입니다. Android에서는 제스처가 기본적으로 비활성화되어 있지만 gestureEnabled 옵션을 통해 활성화할 수 있습니다. Native Stack에서는 JavaScript 스레드 지연 없이 제스처가 네이티브로 작동합니다.
React Navigation은 두 가지 유형의 Stack Navigator를 제공합니다: Native Stack(createNativeStackNavigator)과 JS Stack(createStackNavigator)입니다. 주요 차이점은 애니메이션 실행 위치입니다. Native Stack은 iOS 및 Android의 네이티브 애니메이션 드라이버를 사용하는 반면, JS Stack은 React Native의 JavaScript 스레드를 통해 실행됩니다. 선택은 성능 및 사용자 정의 요구 사항에 따라 달라집니다.
Native Stack은 대부분의 프로젝트에 권장됩니다. JS 스레드를 차단하지 않고 부드러운 60 FPS 애니메이션을 제공하며, iOS에서 시스템 스와이프백 제스처를 지원하고 네이티브 전환(iOS에서는 slide, Android에서는 fade)을 사용합니다. 그러나 Native Stack은 애니메이션 사용자 정의가 제한적입니다. 미리 정의된 전환 세트만 사용할 수 있습니다.
JS Stack은 cardStyleInterpolator를 통해 애니메이션을 완전히 제어할 수 있습니다. 개발자는 스케일링, 회전, 패럴랙스, 사용자 정의 곡선 등 모든 애니메이션을 만들 수 있습니다. 단점은 애니메이션이 JS 스레드에서 실행되어 복잡한 전환 시 약한 기기에서 프레임 드롭이 발생할 수 있다는 점입니다. 70%의 프로젝트에서는 Native Stack으로 충분합니다.
// Native Stack — 권장 구현
import { createNativeStackNavigator } from '@react-navigation/native-stack';
type RootStackParamList = {
Home: undefined;
Profile: { userId: string; name: string };
Settings: undefined;
};
const Stack = createNativeStackNavigator<RootStackParamList>();
function AppNavigator() {
return (
<Stack.Navigator screenOptions={{ headerShown: true }}>
<Stack.Screen name="Home" component={HomeScreen} />
<Stack.Screen name="Profile" component={ProfileScreen} />
<Stack.Screen name="Settings" component={SettingsScreen} />
</Stack.Navigator>
);
}Stack Navigator를 시작하려면 React Navigation과 그 종속성을 설치해야 합니다. 최소 세트에는 @react-navigation/native, @react-navigation/native-stack 및 react-native-screens이 포함됩니다. 설치 후 애플리케이션은 NavigationContainer로 래핑됩니다. 이는 모든 자식 컴포넌트에 네비게이션 상태를 제공하는 컨텍스트입니다.
# React Navigation 종속성 설치
npm install @react-navigation/native @react-navigation/native-stack
npm install react-native-screens react-native-safe-area-context
# iOS의 경우 — pod 설치
cd ios && pod install && cd ..설치 후 Stack.Navigator가 RootStackParamList에 정의된 특정 화면과 함께 생성됩니다. 각 화면은 component prop을 통해 React 컴포넌트에 연결됩니다. 네비게이터는 루트가 되거나 다른 네비게이터(Tab, Drawer) 안에 중첩될 수 있습니다. 구성에는 screenOptions가 사용됩니다. 모든 화면에 공통되거나 각 화면에 개별적으로 사용됩니다.
import { NavigationContainer } from '@react-navigation/native';
import { createNativeStackNavigator } from '@react-navigation/native-stack';
type RootStackParamList = {
Home: undefined;
Details: { itemId: number; title: string };
};
const Stack = createNativeStackNavigator<RootStackParamList>();
export default function App() {
return (
<NavigationContainer>
<Stack.Navigator initialRouteName="Home"
screenOptions={{
headerStyle: { backgroundColor: '#6200ee' },
headerTintColor: '#fff',
gestureEnabled: true,
}}>
<Stack.Screen name="Home" component={HomeScreen}
options={{ title: '홈' }} />
<Stack.Screen name="Details" component={DetailsScreen}
options={({ route }) => ({ title: route.params.title })} />
</Stack.Navigator>
</NavigationContainer>
);
}Stack Navigator는 외관과 동작을 사용자 정의하기 위한 많은 옵션을 제공합니다. 주요 매개변수는 Navigator 수준의 screenOptions 또는 Screen 수준의 options를 통해 설정됩니다. 개발자는 헤더, 전환 애니메이션, 스와이프 제스처, 카드 스타일 및 배경 어두워짐을 구성할 수 있습니다. 설정의 유연성으로 네비게이션을 애플리케이션의 디자인 시스템에 맞출 수 있습니다.
| 옵션 | 유형 | 설명 |
|---|---|---|
| headerShown | boolean | 화면 헤더 표시 또는 숨기기 |
| headerStyle | object | 헤더 바 스타일(backgroundColor, elevation) |
| headerBackTitle | string | «뒤로» 버튼 텍스트(iOS) |
| gestureEnabled | boolean | 스와이프백 제스처 활성화 |
| animation | string | 애니메이션 유형: slide_from_right, fade, none |
| contentStyle | object | 화면 내부 영역 스타일 |
JS Stack의 경우 cardStyleInterpolator를 사용하여 화면 간에 임의의 전환 애니메이션을 만들 수 있습니다. 이는 스케일링, 회전, 패럴랙스, 수평 뒤집기 등 독특한 시각 효과를 구현하기 위한 강력한 도구입니다. 함수는 현재 애니메이션 진행 값(current, next)을 받아 애니메이션 대상 요소의 스타일을 반환합니다.
Stack Navigator는 TypeScript를 통한 완전한 타입 지정을 지원합니다. 이를 위해 RootStackParamList가 정의됩니다. 키가 화면 이름이고 값이 매개변수 유형인 객체 타입입니다. 타입 지정 후 navigation.navigate와 route.params는 자동 완성 및 유형 검사를 받습니다. 이로 인해 컴파일 시 매개변수 전달 오류가 제거됩니다.
type RootStackParamList = {
Home: undefined;
Product: { id: string; category: string };
Checkout: { items: CartItem[]; total: number };
};
// 타입 지정된 화면
type ProductScreenProps = NativeStackScreenProps<RootStackParamList, 'Product'>;
function ProductScreen({ navigation, route }: ProductScreenProps) {
const { id, category } = route.params;
return (
<View>
<Text>상품 {id} — {category}</Text>
<Button title="장바구니에 추가"
onPress={() => navigation.navigate('Checkout', {
items: [{ id, quantity: 1 }],
total: 99.99,
})} />
</View>
);
}Stack Navigator는 화면 그룹화 및 모달 창을 지원합니다. 그룹(Screen Group)은 중복 없이 여러 화면에 공통 설정을 적용할 수 있게 합니다. 모달 창은 stack presentation: 'modal'을 통해 구현됩니다. iOS의 시스템 모달처럼 배경이 어두워지며 화면이 아래에서 열립니다. 이 옵션은 Native Stack에서만 사용할 수 있습니다.
복잡한 네비게이션의 경우 Stack Navigator를 Tab Navigator 또는 Drawer Navigator 안에 중첩할 수 있습니다. 예를 들어 «홈» 탭에는 자체 화면 스택이 있고 «프로필» 탭에도 자체 스택이 있습니다. 이러한 네비게이터 구성은 프로덕션 애플리케이션의 표준 접근 방식입니다. 각 스택은 격리되어 있습니다. 탭 내의 백 스택은 다른 탭에 영향을 주지 않습니다.
// Tab Navigator의 중첩된 스택
const HomeStack = createNativeStackNavigator<HomeStackParamList>();
function HomeStackScreen() {
return (
<HomeStack.Navigator>
<HomeStack.Screen name="Feed" component={FeedScreen} />
<HomeStack.Screen name="PostDetail" component={PostDetailScreen}
options={{ presentation: 'modal' }} />
</HomeStack.Navigator>
);
}
// 공유 옵션이 있는 화면 그룹
<Stack.Navigator>
<Stack.Group screenOptions={{ headerShown: true }}>
<Stack.Screen name="Main" component={MainScreen} />
<Stack.Screen name="About" component={AboutScreen} />
</Stack.Group>
<Stack.Screen name="Auth" component={AuthScreen}
options={{ presentation: 'modal', headerShown: false }} />
</Stack.Navigator>자주 묻는 질문
navigate는 먼저 스택에서 해당 이름의 기존 화면을 찾고, 발견되면 그곳으로 이동합니다. push는 이미 존재하더라도 항상 스택 맨 위에 새 화면을 추가합니다. push는 다른 데이터로 동일한 화면을 열어야 할 때(예: 사용자 프로필) 유용합니다.
매개변수는 navigate 메서드의 두 번째 인수로 전달됩니다: navigation.navigate('Profile', { userId: '123', name: 'John' }). 수신 화면에서는 route.params를 통해 매개변수에 접근할 수 있습니다. TypeScript에서 자동 완성을 위해 매개변수 유형이 RootStackParamList에 정의됩니다.
Stack Navigator는 선형 네비게이션(화면 → 세부 정보 → 편집)에 적합합니다. Tab Navigator는 애플리케이션의 병렬 섹션(홈, 검색, 프로필)에 적합합니다. 프로덕션 프로젝트에서는 이들을 결합합니다. Tab Navigator에 각 탭에 대한 여러 Stack Navigator가 포함됩니다.
기본적으로 Stack Navigator는 루트 화면을 제외한 모든 화면의 헤더에 «뒤로» 버튼을 추가합니다. iOS에서는 왼쪽 가장자리에서 스와이프 제스처도 작동합니다. navigation.goBack() 메서드는 스택에서 현재 화면을 제거하고 사용자를 이전 화면으로 되돌립니다.
Native Stack은 미리 정의된 애니메이션(slide_from_right, fade, none)을 제공합니다. 완전한 사용자 정의를 위해 JS Stack을 cardStyleInterpolator와 함께 사용합니다. 이는 각 애니메이션 프레임에서 카드 스타일을 반환하는 함수입니다. 이를 통해 스케일링, 패럴랙스, 3D 회전 등 모든 전환을 만들 수 있습니다.
요약
턴키 방식의 모바일 애플리케이션을 개발해 드립니다
IT Sectr는 2017년부터 스타트업과 기업을 위한 iOS 및 Android 애플리케이션을 만듭니다. 저희가 상담해 드리고 최적의 솔루션을 제안하겠습니다.