공부/ReactNative

[ReactNative] Navigation | 처음 배우는 리액트네이티브 8장

hyunh404 2025. 1. 28. 18:38
728x90

 

 

모바일 애플리케이션은 일반적으로 다양한 화면이 상황에 맞게 전환되며 나타난다.

그렇기 때문에 내비게이션은 가장 중요한 기능 중 하나이다.

 

+ 리액트 네이티브에서는 외부 라이브러리를 이용해야 한다.

 

 

 

리액트 내비게이션

 

 

  • 내비게이션을 쉽고 간단하게 관리할 수 있도록 도와준다.
  • 지원 종류 : 스택(stack), 탭(tab), 드로어(drawer) 내비게이션
  • 구조 : NavigationContainer 컴포넌트 ▷ Navigator 컴포넌트 ▷ Screen 컴포넌트

 

1️⃣ Screen 컴포넌트

 

  • 화면으로 사용되는 컴포넌트
  • name (= 화면 이름), component (= 화면으로 사용될 컴포넌트 전달) 속성 지정해야함
  • name은 반드시 서로 다른 값
  • 화면으로 사용되는 컴포넌트에는 항상 navigationroute가 props로 전달된다.

 

2️⃣ Navigator 컴포넌트

 

  • 화면을 관리하는 중간 관리자 역할
  • 내비게이션 구성, 여러개의 Screen 컴포넌트를 갖고 있다.

 

3️⃣ NavigationContainer 컴포넌트

 

  • 내비게이션 계층 구조와 상태 관리하는 컨테이너 역할
  • 모든 내비게이션 구성 요소를 감싼 최상위 컴포넌트

 

1. 내비게이션 속성 수정 방법

작은 범위의 설정일수록 우선순위가 높다.

 

 

1️⃣ 화면으로 사용되는 컴포넌트 props로 전달되는 navigation을 이용한 수정

 

  • 해당 화면에만 적용
  • 우선 순위 = 1

 

2️⃣ Screen 컴포넌트 속성으로 수정

 

  • 해당 화면에만 적용
  • 우선 순위 = 2

 

3️⃣ Navigator 컴포넌트 속성으로 수정

 

  • 자식 컴포넌트로 존재하는 모든 컴포넌트에 적용
  • 우선 순위 = 3

 


 

 

이제 실습을 위해 라이브러리를 설치해주겠다.

 

리액트 내비게이션은 기능 별로 모듈리 분리되어 있어 개별적으로 추가 라이브러리도 설치해주어야 한다.

 

 npm install --save @react-navigation/native
npm install react-native-gesture-handler react-native-reanimated react-native-screens react-native-safe-area-context @react-native-community/masked-view

 

 

728x90

 


 

 

스택 내비게이션

 

 

  • 일반적으로 가장 많이 사용되는 내비게이션
  • 현재 화면 위에 다른 화면을 쌓으면서(push) 화면 이동하는 것이 특징
  • 가장 위에 있는 화면 들어내면(pop) 이전 화면으로 돌아갈 수 있다.
  • ex. 채팅 - 채팅방 입장 / 여러 목록 중 특정 항목 상세 화면으로 이동 시 사용
npm install @react-navigation/stack

 

 

createStackNavigator 함수를 이용해 스택 내비게이션을 생성하고 화면을 구성하는 Screen 컴포넌트와 Scrren을 관리하는 Navigator 컴포넌트를 만들어주었다.

내비게이션을 사용하기 위해 App.jsx에서 NavigationContainer 컴포넌트로 작성한 스택 내비게이션을 감싸주었다.

 

👇코드 보기

더보기
import React from 'react';
import { createStackNavigator } from '@react-navigation/stack';
import Home from '../screens/Home';
import List from '../screens/List';
import Item from '../screens/Item';

const Stack = createStackNavigator();

const StackNavigation = () => {
    return (
        <Stack.Navigator
            screenOptions={{
                headerTitleAlign: 'center', // 제목 가운데 정렬
                headerStyle: {
                    borderBottomWidth: 0, // 경계선 제거
                    elevation: 0, // Android 그림자 제거
                    shadowOpacity: 0, // iOS 그림자 제거
                },
            }}
        >
            <Stack.Screen name="Home" component={Home} />
            <Stack.Screen name="List" component={List} />
            <Stack.Screen name="Item" component={Item} />
        </Stack.Navigator>
    )
}

export default StackNavigation;
import { NavigationContainer } from '@react-navigation/native';
import React from 'react';
import StackNavigation from './navigations/Stack';

const App = () => {
  return (
    <NavigationContainer>
        <StackNavigation />
    </NavigationContainer>
  )
}

export default App

 

 

현재 Home 스크린이 가장 먼저 정의되어 있어 처음 화면에 뜨지만 순서를 변경하기 위한 방법으로는 다음과 같은 방법이 있다.

 

1. 직접적인 컴포넌트 순서를 변경하는 방법

2. initialRouteName 속서을 이용해 첫 화면을 지정하는 방법

 

<Stack.Navigator initialRouteName='List'>
    <Stack.Screen name="Home" component={Home} />
    <Stack.Screen name="List" component={List} />
    <Stack.Screen name="Item" component={Item} />
</Stack.Navigator>

 

 


 

1. 화면 이동

  • navigate 함수 : 원하는 화면으로 이동하는 데 사용
  • 전달되는 화면 이름은 Screen 컴포넌트 name 값 중 하나여야함
const Home = ({ navigation }) => {
    return (
        <Container>
            <StyedText>Home</StyedText>
            <CustomButton onPress={() => navigation.navigate('List')}>
                <ButtonText>Go to the List Screen</ButtonText>
            </CustomButton>
        </Container>
    )
}

화면 이동

 

 

2. 헤더 수정

1️⃣ 타이틀 수정

 

  • Screen 컴포넌트 name 속성 변경 → name 속성을 이용하는 모든 곳 수정해야한다는 단점
  • headerTitle 속성 이용 → 개별 화면 설정 수정, Screen 컴포넌트의 options 이용
  • 모든 화면에서 같은 타이틀 나타내려면 Navigator 컴포넌트의 screen Options 속성에 headerTitle을 지정

 

2️⃣ 스타일 수정

 

  • headerstyle : 헤더 스타일 수정
  • headerTitleStyle : 헤더 타이틀 컴포넌트 스타일 수정
  • header TitleAlign : 정렬, left(기본값)와 center 두 가지 값 중 한 가지만 설정

👇코드 보기

더보기
import React from 'react';
import { createStackNavigator } from '@react-navigation/stack';
import Home from '../screens/Home';
import List from '../screens/List';
import Item from '../screens/Item';

const Stack = createStackNavigator();

const StackNavigation = () => {
    return (
        <Stack.Navigator
            initialRouteName='Home'
            screenOptions={{
                headerTitleAlign: 'center', // 제목 가운데 정렬
                cardStyle: { backgroundColor: '#ffffff' }, // 화면 전체 차지
                headerStyle: {
                    height: 110,
                    backgroundColor: '#95a5a6',
                    borderBottomWidth: 5,
                    borderBottomColor: '#34495e',
                },
                headerTitleStyle: { color: '#fff', fontSize: 24, }
            }}
        >
            <Stack.Screen name="Home" component={Home} />
            <Stack.Screen
                name="List"
                component={List}
                options={{ headerTitle: 'List Screen' }}
            />
            <Stack.Screen name="Detail" component={Item} />
        </Stack.Navigator>
    )
}

export default StackNavigation;

 

 

3️⃣ 타이틀 컴포넌트 변경

 

  • headerTitle 속성에 컴포넌트 반환 함수 지정 → 타이틀 컴포넌트 반환하는 컴포넌트로 변경할 수 있다.
  • 함수가 설정되면 해당 함수의 파라미터로 style과 tintColor 등이 포함된 객체가 전달됨
headerTitle: ({ style }) => (
	<MaterialCommunityIcons name="react" style={style} />
),

headerTitle에 함수 전달

 

 

4️⃣ 버튼 수정

 

  • headerBackTitleVisible : 뒤로 가기 버튼 타이틀 렌더링 여부 설정
  • headerTintColor : 버튼 타이틀, 이미지 색 동일하게 변경 (header TitleStyle /  headerBackTitleStyle의 우선순위가 더 높으므로 다른 스타일과 겹치지 않는 게 중요)
  • headerBackImage : 뒤로가기 버튼 동일한 이미지 렌더링 설정
  • headerLeft : 헤더 왼쪽 버튼 전체 변경
  • headerRight : 헤더 오른쪽 버튼 전체 변경
  • useLayoutEffect Hook : useEffect Hook과 사용법 동일, 주요 차이점은 컴포넌트가 업데이트된 직후 화면이 렌더링되기 전에 실행된다는 것
<Stack.Screen
    name="List"
    component={List}
    options={{
        headerTitle: 'List Screen',
        headerBackTitleVisible: true,
        headerBackTitle: 'Prev',
        headerTitleStyle: { fontSize: 24 },
        headerTintColor: '#e74c3c',
        headerBacklmage: ({ tintColor }) => {
        const style = {
                marginRight: 5,
                marginLeft: Platform.OS === 'ios' ? 11 : 8,
            };
            return (
                <MaterialCommunityIcons
                    name="keyboard-backspace"
                    size={30}
                    color={tintColor}
                    style={style}
                />
            );
        },
    }}
/>
 useLayoutEffect(() => {
        navigation.setOptions({
            headerBackTitleVisible: false,
            headerTintColor: '#fff',
            headerLeft: ({ onPress, tintColor }) => {
                return (
                    <MaterialCommunityIcons
                        name="keyboard-backspace"
                        size={30}
                        style={{ marginLeft: 11 }}
                        color={tintColor}
                        onPress={onPress}
                    />
                );
            },
            headerRight: ({ tintColor }) => (
                <MaterialCommunityIcons
                    name="home-variant"
                    size={30}
                    style={{ marginRight: 11 }}
                    color={tintColor}
                    onPress={() => navigation.popToTop()}
                />
            ),
        })
}, []);

 

 

5️⃣ 헤더 감추기

 

  • headerMode : Navigator 컴포넌트의 속성, 헤더를 렌더링하는 방법 설정 (float: (iOS) 헤더 상단 유지, 하나의 헤더 사용 / screen: (Android) 각 화면마다 헤더 가짐 / none: 헤더 렌더링 X)
  • headerShown : 화면 옵션, Navigator 컴포넌트의 screenOptions에 설정하면 전체 화면의 헤더가 보이지 않게 설정 가능

 


 

 

탭 내비게이션

 

 

탭 내비게이션은 보통 위, 아래에 위치하며,

탭 버튼을 누르면 버튼과 연결된 화면으로 이동한다.

 

실습을 위해 추가적인 라이브러리를 설치해주겠다.

 npm install @react-navigation/bottom-tabs

 

 

createBottomTabNavigator를 이용해 탭 내비게이션을 만들고 탭 스크린을 설정해 컴포넌트를 정의해주었다.

 

import React from 'react';
import { createBottomTabNavigator } from '@react-navigation/bottom-tabs'; 
import { Mail, Meet, Settings } from '../screens/TabScreen';

const Tab = createBottomTabNavigator();

const TabNavigation = () => {
    return (
        <Tab.Navigator>
            <Tab.Screen name="Mail" component={Mail} />
            <Tab.Screen name="Meet" component={Meet} />
            <Tab.Screen name="Settings" component={Settings} />
        </Tab.Navigator>
    )
}

export default TabNavigation;

 


 

1. 탭 바 수정하기

1️⃣ 버튼 아이콘 설정

 

  • tabBarlcon : 아이콘이 들어갈 자리에 해당 컴포넌트 렌더링, color, size, focused값을 포함한 객체가 파라미터로 전달됨
  • 모든 버튼 아이콘 관리하고 싶은 경우 : Navigator 컴포넌트 screenOptions 속성 사용

👇코드 보기

더보기
import React from 'react';
import { createBottomTabNavigator } from '@react-navigation/bottom-tabs';
import { Mail, Meet, Settings } from '../screens/TabScreen';
import { MaterialCommunityIcons } from 'react-native-vector-icons';

const TabIcon = ({ name, size, color }) => {
    return <MaterialCommunityIcons name={name} size={size} color={color} />;
};

const Tab = createBottomTabNavigator();

const TabNavigation = () => {
    return (
        <Tab.Navigator
            initialRouteName="Settings"
            screenOptions={({ route }) => ({
                tabBarIcon: props => {
                    let name = '';
                    if (route.name === 'Mail') name = 'email';
                    else if (route.name === 'Meet') name = 'video';
                    else name = 'cog';
                    return TabIcon({ ...props, name });
                },
            })}
        >
            <Tab.Screen
                name="Mail"
                component={Mail}
                options={{
                    tabBarIcon: props => TabIcon({ ...props, name: 'email' }),
                }}
            />
            <Tab.Screen
                name="Meet"
                component={Meet}
                options={{
                    tabBarIcon: props => TabIcon({ ...props, name: 'video' }),
                }}
            />
            <Tab.Screen
                name="Settings"
                component={Settings}
                options={{
                    tabBarIcon: props => TabIcon({ ...props, name: 'cog' }),
                }}
            />
        </Tab.Navigator >
    )
}

export default TabNavigation;

 

 

2️⃣ 라벨 수정

 

  • Screen 컴포넌트의 name 값이 기본값
  • tabBarLabel : 탭 바 라벨값 변경
  • tabBarLabelStyle : 라벨 위치 조정, below-icon과 beside-icon 두 값만 설정 가능
  • tabBarShowLabel : 라벨 렌더링 설정
  • tabBarActiveTintColor / tabBarInactiveTintColor : 버튼 활성, 비활성 상태 색 설정
💡
tabBarOptions가 React Navigation v6에서는 더 이상 사용되지 않는다.
React Navigation v6 이상에서는 tabBarOptions 대신 **screenOptions**와 tabBarStyle, tabBarLabelStyle 등의 속성을 사용해야 한다.

tabBarLabelPosition: 'beside-icon',

 

 

focused 값에 따라 아이콘을 변경할 수도 있다.

 

<Tab.Screen
    name="Settings"
    component={Settings}
    options={{
        tabBarIcon: props => TabIcon({
            ...props,
            name: props.focused ? 'cog' : 'cog-outline',
        }),
    }}
/>

 

728x90