[React Native] Native Stack Navigator
π₯ 1. Native Stack Navigator
- Native Stack Navigatorλ κ° μ νλ©΄μ΄ μ€νμ 맨 μμ λ°°μΉλμ΄ νλ©΄ κ° μ νμ μ 곡νλ λ°©μμ μ 곡
- iOSμμλ λ€μ΄ν°λΈ APIμΈ UINavigationControllerλ₯Ό μ¬μ©νκ³ Androidμμλ Fragmentλ₯Ό μ¬μ©νμ¬ createNativeStackNavigatorμΌλ‘ ꡬμΆλ λ€λΉκ²μ΄μ μ΄ λ€μ΄ν°λΈλ‘ ꡬμΆλ μ±κ³Ό μμ ν λμΌν λμκ³Ό μ±λ₯ νΉμ±μ κ°λλ‘ν¨
yarn add @react-navigation/native-stack
π₯ 2. Props
id
: λ€λΉκ²μ΄ν°μ λν μ νμ μΈ κ³ μ μλ³μμ λλ€. μ΄λ₯Ό μ΄μ©νμ¬ navigation.getParentλ₯Ό μ¬μ©νμ¬ μμ λ€λΉκ²μ΄ν°μμ μ΄ λ€λΉκ²μ΄ν°λ₯Ό μ°Έμ‘°ν μ μμ΅λλ€.initialRouteName
: λ€λΉκ²μ΄ν°κ° μ²μ λ‘λλ λ λ λλ§ν λΌμ°νΈμ μ΄λ¦μ λλ€. μ΄ μ΄λ¦μ λ€λΉκ²μ΄ν°κ° μμλ λ νμν μ΄κΈ° νλ©΄μ κ²°μ ν©λλ€.screenOptions
: λ€λΉκ²μ΄ν° λ΄μ νλ©΄μ λν κΈ°λ³Έ μ΅μ μ λλ€. μ΄ μ΅μ μ λ€λΉκ²μ΄ν° λ΄ λͺ¨λ νλ©΄μ μ μ©λ©λλ€. μ΄λ₯Ό ν΅ν΄ λͺ¨λ νλ©΄μ λμΌν μ€μ μ μ μ©νκ±°λ μΌλΆ νλ©΄μλ§ μ μ©ν νΉμ μ€μ μ μ€μ ν μ μμ΅λλ€.
π₯ 3. Options
title
: λ€λΉκ²μ΄μ ν€λμ κΈ°λ³Έ μ λͺ©μΌλ‘ μ¬μ©λ λ¬Έμμ΄μ λλ€.headerBackButtonMenuEnabled
: iOS λ²μ μ΄ 14 μ΄μμΌ λ λ°± λ²νΌμ λ‘±νλ μ€νλ©΄ λ©λ΄λ₯Ό 보μ¬μ€μ§ μ¬λΆλ₯Ό λνλ΄λ λΆμΈ κ°μ λλ€. κΈ°λ³Έκ°μ trueμ λλ€.headerBackVisible
: ν€λμ λ°± λ²νΌμ΄ νμλλμ§ μ¬λΆμ λλ€. headerLeftμ ν¨κ» μ¬μ©νμ¬ λ°± λ²νΌμ νμν μ μμ΅λλ€.headerBackTitle
: iOSμμ λ°± λ²νΌμ μ¬μ©ν νμ΄ν λ¬Έμμ΄μ λλ€. μ΄μ νλ©΄μ μ λͺ©μ΄ κΈ°λ³Έκ°μ΄λ©° 곡κ°μ΄ λΆμ‘±ν κ²½μ° βBackβμΌλ‘ νμλ©λλ€.headerBackTitleVisible
: λ°± λ²νΌ νμ΄νμ΄ νμλλμ§ μ¬λΆμ λλ€.headerBackTitleStyle
: ν€λ λ°± νμ΄νμ μ€νμΌ κ°μ²΄μ λλ€. fontFamily, fontSize λ±μ μμ±μ μ§μν©λλ€.headerBackImageSource
: ν€λμμ λ°± λ²νΌμ νμν μ΄λ―Έμ§μ λλ€. νλ«νΌμ λ°λΌ κΈ°λ³Έκ°μΌλ‘ iOSμλ chevron, Androidμλ νμ΄νκ° μ¬μ©λ©λλ€.headerLargeStyle
: ν° νμ΄νμ΄ νμλ λ ν€λμ μ€νμΌμ λλ€. headerLargeTitleμ΄ trueμ΄κ³ μ€ν¬λ‘€ κ°λ₯ν λ΄μ©μ΄ ν€λμ μΌμΉνλ κ°μ₯μ리μ λλ¬ν λ ν° νμ΄νμ΄ νμλ©λλ€.headerLargeTitle
: μ€ν¬λ‘€ μ μΌλ°μ μΈ ν€λλ‘ μΆμλλ ν° μ λͺ©μ΄ μλ ν€λλ₯Ό νμ±νν μ§ μ¬λΆμ λλ€. ScrollView λλ FlatListμ κ°μ μ€ν¬λ‘€ κ°λ₯ν λ·°λ‘ νλ©΄ λ΄μ©μ κ°μΈμΌ ν©λλ€.headerLargeTitleShadowVisible
: ν° μ λͺ©μ΄ νμλ λ ν€λμ λλ‘ μλμ°κ° 보μ΄λμ§ μ¬λΆμ λλ€.headerShown
: ν€λλ₯Ό νμν μ§ μ¬λΆμ λλ€. κΈ°λ³Έμ μΌλ‘ ν€λκ° νμλ©λλ€. falseλ‘ μ€μ νλ©΄ ν€λλ₯Ό μ¨κΉλλ€.headerStyle
: ν€λμ μ€νμΌ κ°μ²΄μ λλ€. backgroundColor, headerShadowVisible λ±μ μμ±μ μ§μν©λλ€.headerTransparent
: λ€λΉκ²μ΄μ λ°κ° ν¬λͺ νμ§ μ¬λΆλ₯Ό λνλ΄λ λΆμΈ κ°μ λλ€. trueλ‘ μ€μ νλ©΄ ν€λκ° μ λμ μΌλ‘ μμΉνμ¬ λ΄μ© μλλ‘ κ²Ήμ³μ§λλ‘ λ§λλλ€.headerBlurEffect
: ν¬λͺ ν ν€λμ λΈλ¬ ν¨κ³Όμ λλ€. headerTransparent μ΅μ μ΄ trueλ‘ μ€μ λμ΄μΌ ν©λλ€.headerBackground
: ν€λμ λ°°κ²½μΌλ‘ μ¬μ©ν React Elementλ₯Ό λ λλ§νλ ν¨μμ λλ€. μ΄λ―Έμ§λ κ·ΈλΌλμΈνΈμ κ°μ λ°°κ²½μ μ¬μ©νλ λ° μ μ©ν©λλ€.headerTintColor
: ν€λμ ν΄νΈ μμμ λλ€. λ°± λ²νΌκ³Ό μ λͺ©μ μμμ λ³κ²½ν©λλ€.headerLeft
: ν€λ μΌμͺ½μ νμν μμλ₯Ό λ°ννλ ν¨μμ λλ€. λ°± λ²νΌμ λ체ν©λλ€.headerRight
: ν€λ μ€λ₯Έμͺ½μ νμν μμλ₯Ό λ°ννλ ν¨μμ λλ€.headerTitle
: ν€λμμ μ¬μ©ν λ¬Έμμ΄ λλ React Elementλ₯Ό λ°ννλ ν¨μμ λλ€. κΈ°λ³Έκ°μ νλ©΄μ μ λͺ© λλ μ΄λ¦μ λλ€.headerTitleAlign
: ν€λ μ λͺ©μ μ΄λ»κ² μ λ ¬ν μ§ λνλ΄λ κ°μ λλ€. left, center λ±μ κ°μ΄ κ°λ₯νμ§λ§ iOSμμλ νμ centerλ‘ κ³ μ λμ΄ μμ΅λλ€.headerTitleStyle
: ν€λ μ λͺ©μ μ€νμΌ κ°μ²΄μ λλ€. fontFamily, fontSize λ±μ μμ±μ μ§μν©λλ€.headerSearchBarOptions
: iOSμμ λ€μ΄ν°λΈ κ²μ λ°λ₯Ό λ λλ§νλ μ΅μ μ λλ€. autoCapitalize, autoFocus λ±μ μμ±μ μ§μν©λλ€.header
: κΈ°λ³Έ ν€λ λμ μ μ¬μ©ν 컀μ€ν ν€λλ₯Ό μ§μ νλ ν¨μμ λλ€. navigation, route, options, backμ ν¬ν¨νλ κ°μ²΄λ₯Ό λ°μ΅λλ€.statusBarAnimation
: μν νμμ€ μ λλ©μ΄μ μ μ€μ νλ κ°μ λλ€. iOSμμλ fade κΈ°λ³Έκ°μ΄λ©° Androidμμλ noneμ λλ€.statusBarHidden
: μ΄ νλ©΄μμ μν νμμ€μ μ¨κΈΈμ§ μ¬λΆμ λλ€.statusBarStyle
: μν νμμ€ μμμ μ€μ νλ κ°μ λλ€. auto, inverted, dark, light λ±μ κ°μ΄ κ°λ₯ν©λλ€.statusBarColor
: μν νμμ€ μμμ μ€μ νλ κ°μ λλ€. Androidμμλ§ μ§μλ©λλ€.statusBarTranslucent
: μν νμμ€μ ν¬λͺ λλ₯Ό μ€μ νλ λΆμΈ κ°μ λλ€. Androidμμλ§ μ§μλ©λλ€.contentStyle
: νλ©΄ λ΄μ©μ μ€νμΌ κ°μ²΄μ λλ€.customAnimationOnGesture
: μ μ€μ²λ₯Ό μ¬μ©νμ¬ νλ©΄μ λ«μ λ μ 곡λ μ λλ©μ΄μ μ μ¬μ©ν μ§ μ¬λΆλ₯Ό λνλ΄λ λΆμΈ κ°μ λλ€.fullScreenGestureEnabled
: μ 체 νλ©΄μμ μ μ€μ²λ₯Ό μ¬μ©νμ¬ νλ©΄μ λ«μμ§ μ¬λΆλ₯Ό λνλ΄λ λΆμΈ κ°μ λλ€.gestureEnabled
: μ΄ νλ©΄μμ μ μ€μ²λ₯Ό μ¬μ©νμ¬ λ«μ μ μλμ§ μ¬λΆμ λλ€.animationTypeForReplace
: μ΄ νλ©΄μ΄ λ€λ₯Έ νλ©΄μ λ체ν λ μ¬μ©ν μ λλ©μ΄μ μ νμ λλ€.animation
: νλ©΄μ νΈμνκ±°λ νν λ νλ©΄μ μ΄λ»κ² μ λλ©μ΄μ νν μ§ λνλ΄λ κ°μ λλ€.presentation
: νλ©΄μ΄ νμλ λ°©λ²μ λνλ΄λ κ°μ λλ€.orientation
: νλ©΄μ λμ€νλ μ΄ λ°©ν₯μ μ€μ νλ κ°μ λλ€.autoHideHomeIndicator
: ν μΈλμΌμ΄ν°κ° μ¨κ²¨μ ΈμΌ νλμ§ μ¬λΆλ₯Ό λνλ΄λ λΆμΈ κ°μ λλ€.gestureDirection
: νλ©΄μ λ«κΈ° μν΄ μ€μμ΄νν λ°©ν₯μ μ€μ νλ κ°μ λλ€.animationDuration
: iOSμμ slide_from_bottom, fade_from_bottom, fade λ° simple_push μ νμ μ§μ μκ°μ λ³κ²½νλ κ°μ λλ€.navigationBarColor
: λ€λΉκ²μ΄μ λ° μμμ μ€μ νλ κ°μ λλ€.navigationBarHidden
: λ€λΉκ²μ΄μ λ°λ₯Ό μ¨κΈΈμ§ μ¬λΆλ₯Ό λνλ΄λ λΆμΈ κ°μ λλ€.freezeOnBlur
: λΉνμ±νλ νλ©΄μ΄ λ¦¬λ λλ§λμ§ μλλ‘ λ°©μ§ν μ§ μ¬λΆλ₯Ό λνλ΄λ λΆμΈ κ°μ λλ€.
π₯ 4. Events
transitionStart
: μ΄ μ΄λ²€νΈλ νμ¬ νλ©΄μ μ ν μ λλ©μ΄μ μ΄ μμλ λ λ°μν©λλ€.- μ΄λ²€νΈ λ°μ΄ν°:
e.data.closing
: νλ©΄μ΄ μ΄λ¦¬λμ§ λ«νλμ§λ₯Ό λνλ΄λ λΆμΈ κ°μ λλ€.
μμ:
javascriptCopy code React.useEffect(() => { const unsubscribe = navigation.addListener('transitionStart', (e) => { // μ¬κΈ°μ 무μΈκ°λ₯Ό μνν©λλ€ }); return unsubscribe; }, [navigation]);
- μ΄λ²€νΈ λ°μ΄ν°:
transitionEnd
: μ΄ μ΄λ²€νΈλ νμ¬ νλ©΄μ μ ν μ λλ©μ΄μ μ΄ μ’ λ£λ λ λ°μν©λλ€.- μ΄λ²€νΈ λ°μ΄ν°:
e.data.closing
: νλ©΄μ΄ μ΄λ¦¬κ±°λ λ«νλμ§λ₯Ό λνλ΄λ λΆμΈ κ°μ λλ€.
μμ:
javascriptCopy code React.useEffect(() => { const unsubscribe = navigation.addListener('transitionEnd', (e) => { // μ¬κΈ°μ 무μΈκ°λ₯Ό μνν©λλ€ }); return unsubscribe; }, [navigation]);
- μ΄λ²€νΈ λ°μ΄ν°: