밥풀의 개발일지

expo-router에 대한 간단한 이야기 본문

개발

expo-router에 대한 간단한 이야기

밥풀42 2024. 11. 28. 09:02

Expo Router: 파일 시스템 기반 라우팅 개요

Expo Router는 React Native에서 파일 시스템을 기반으로 라우트를 정의하는 방식입니다. 웹의 Next.js와 유사한 라우팅 방식을 모바일 애플리케이션에 도입함으로써, 경로 관리와 유지 보수를 쉽게 합니다. 파일의 경로와 구조에 따라 자동으로 라우트가 설정되기 때문에 명시적으로 라우트를 정의할 필요 없이, 직관적이고 간편하게 네비게이션을 구성할 수 있습니다.

1. 파일 구조가 라우트가 된다

파일 시스템 기반 라우팅에서는 디렉터리와 파일이 경로와 일치합니다. 예를 들어, 아래와 같은 파일 구조가 있다고 가정합시다:

/app
  |-- index.js
  |-- about.js
  |-- profile
        |-- index.js
        |-- settings.js

  • /app/index.js: 기본 경로 (/)에 해당합니다.
  • /app/about.js: /about 경로로 접근할 수 있습니다.
  • /app/profile/index.js: /profile 경로에 대응합니다.
  • /app/profile/settings.js: /profile/settings 경로에 해당합니다.

이처럼 파일 구조가 곧 앱의 내비게이션 경로가 되기 때문에, 복잡한 라우트 설정을 일일이 할 필요가 없습니다.

2. 동적 라우트와 매개변수

Expo Router에서는 동적 라우트도 쉽게 정의할 수 있습니다. 파일 이름에 대괄호 []를 사용하여 매개변수를 정의합니다.

예를 들어, /app/profile/[userId].js 파일이 있다면, /profile/123와 같은 경로로 접근할 수 있으며, userId 값에 해당하는 매개변수를 받아 사용할 수 있습니다. 이렇게 동적 매개변수를 이용하면 사용자마다 다른 프로필 화면을 쉽게 구현할 수 있습니다.

3. 네비게이션과 구성 요소

Expo Router는 React Navigation을 바탕으로 동작하기 때문에, Stack, Tab 등 다양한 네비게이션 타입을 손쉽게 구성할 수 있습니다. 예를 들어, tabs.js 파일을 생성하여 탭 네비게이션을 구현하고 각 탭에 연결될 화면을 폴더와 파일로 나누어 관리할 수 있습니다. 이는 웹 애플리케이션의 내비게이션 구조와 매우 유사하게 느껴지므로 웹 개발 경험이 있는 개발자에게 친숙한 방식입니다.

4. 사례

아래의 구조는 캡스톤을 진행하면서 네비게이션 바를 만든 것입니다.

“전체메뉴 - 여행 추천 - ai챗봇 - 마이페이지 - 내 여행” 순으로 하단바가 만들어져있습니다.

app
├── (tabs)
│   ├── _layout.tsx
│   ├── index.tsx
│   ├── menu.tsx
│   ├── my-page.tsx
│   ├── my-travel.tsx
│   └── travel-recommendation.tsx
├── +not-found.tsx
└── _layout.tsx

app/_layout.tsx

import { Stack } from 'expo-router/stack';
import React from 'react';

export default function RootLayout() {
	return (
		<Stack>
			<Stack.Screen name="(tabs)" option={{ headerShown: false }} />
		<Stack>
	);
}

app/(tabs)/_layout.tsx

// _layout.tsx (이 파일은 기본 레이아웃을 설정하며, 각 페이지의 공통 레이아웃을 정의합니다.)
import { Tabs } from 'expo-router';
import React from 'react';
import {TabBarIcon} from '../../components/navigation/TabBarIcon';

export default function TabLayout() {
  return (
    <Tabs>
      <Tabs.Screen name="menu" options={{
        title: '전체메뉴',
        tabBarIcon: ({ color, size }) => <TabBarIcon name="menu" color={color} size={size} />,
        headerShown: false
        }} />
      <Tabs.Screen name="travel-recommendation" options={{
        title: '여행지 추천',
        tabBarIcon: ({ color, size }) => <TabBarIcon name="map" color={color} size={size} />,
        headerShown: false
        }} />
      <Tabs.Screen name="index" options={{
        title: 'AI 채팅',
        tabBarIcon: ({ color, size }) => <TabBarIcon name="chatbubble-ellipses-sharp" color={color} size={size} />,
        headerShown: false
        }} />
      <Tabs.Screen name="my-page" options={{
        title: '마이페이지',
        tabBarIcon: ({ color, size }) => <TabBarIcon name="person" color={color} size={size} />,
        headerShown: false
        }} />
      <Tabs.Screen name="my-travel" options={{
        title: '내 여행',
        tabBarIcon: ({ color, size }) => <TabBarIcon name="calendar" color={color} size={size} />,
        headerShown: false
        }} />

    </Tabs>
  );
}

이러한 식으로 만들 수 있습니다.