모바일/React Native

React Native 설치 및 라우팅

pigggulggul 2024. 11. 25. 00:30

모바일 앱 플랫폼 개발

App Platform 선택 이유

동기들과 프로젝트 주제를 논의하던 중, AI모바일 관련 프로젝트가 주목받고 있음을 알게 되었습니다. 그동안 주로 프론트엔드 프로젝트를 진행해왔던 경험에 더해, 모바일 관련 프로젝트에도 도전하고자 앱 개발 및 배포를 목표로 삼았습니다.

React Native 선택 이유

타겟 사용자는 10대에서 30대로, 안드로이드와 iOS 기기 사용자 모두를 고려해 플레이스토어애플 앱스토어에 배포하기로 결정했습니다. 플랫폼 선택 과정에서 React Native와 Flutter를 검토한 결과, 다음 이유로 React Native를 채택하게 되었습니다:

  1. 러닝 커브의 용이성
    • React + TypeScript 환경에서의 개발 경험이 많아, Flutter의 Dart 언어에 비해 학습 장벽이 낮다고 판단했습니다.
  2. 재사용 가능한 라이브러리
    • Redux, Jest, Storybook 등 기존 React 프로젝트에서 사용했던 다양한 라이브러리를 그대로 활용할 수 있었습니다.
  3. OTA 업데이트 지원
    • 다수의 프로젝트 경험에서 QA 작업이 빈번했는데, OTA(Over-the-Air) 업데이트로 수정 사항을 빠르게 반영할 수 있다는 점이 매력적이었습니다.
  4. CSS 스타일링
    • CSS 활용이 가능해, 빠른 스타일링 작업이 가능했습니다. 이는 개발 속도를 극대화할 수 있는 저만의 강점으로 작용했습니다.

기술 스택

  • 프레임워크 및 도구: React Native, Expo, VS Code
  • 테스팅 도구: Jest, Storybook
  • 상태 관리: Redux Toolkit
  • 스타일링: NativeWind
  • 푸시 알림: Firebase Cloud Messaging(FCM) vs React Native Push Notification
  • 인증: Firebase Authentication vs OAuth
  • 빌드: ESBuild 번들러

푸시 알림과 인증 선택 고민

Firebase를 활용할 경우, 푸시 알림과 인증 모두 Firebase 기반으로 통합 운영하는 방안을 검토 중입니다.


시작하기

설치 과정

다음 명령어를 사용하여 프로젝트를 생성합니다

npx create-expo-app@latest

기본적인 방식으로 VS Code를 활용해 프로젝트를 생성하였습니다. 생성된 package.json 파일을 확인하면, 실행 방법과 관련된 스크립트가 포함되어 있습니다

"scripts": {
    "start": "expo start",
    "reset-project": "node ./scripts/reset-project.js",
    "android": "expo start --android",
    "ios": "expo start --ios",
    "web": "expo start --web",
    "test": "jest --watchAll",
    "lint": "expo lint"
  },

여기서 expo start, jest 등을 포함한 여러 명령어를 확인할 수 있습니다

기본적으로 다음 명령어를 통해 프로젝트를 시작할 수 있습니다

npm start

실행 결과는 다음과 같습니다

› Scan the QR code above with Expo Go (Android) or the Camera app (iOS)

› Web is waiting on [<http://localhost:8081>](<http://localhost:8081/>)

› Using Expo Go
› Press s │ switch to development build

› Press a │ open Android
› Press w │ open web
...

QR 코드와 웹 주소가 표시되며, 이를 통해 Expo Go를 사용하거나 명령어를 입력해 접속할 수 있습니다. 필자는 w를 눌러 웹에서 접속하는 방식으로 성공적으로 실행하였습니다.

그 외 커맨드

npx expo start 개발 서버를 시작합니다.

npx expo prebuild Prebuild를 사용하여 기본 Android 및 iOS 디렉토리를 생성합니다 .
npx expo run:android 네이티브 Android 앱을 로컬에서 컴파일합니다.
npx expo run:ios 네이티브 iOS 앱을 로컬에서 컴파일합니다.
npx expo install package-name 새 라이브러리를 설치하거나 업데이트를 수행합니다.
npx expo lint ESLint를 설정하고 구성합니다 .

참고 ( https://docs.expo.dev/develop/tools/ )

EAS CLI (Expo Application Services)

실행이 성공적으로 완료되었으므로 EAS CLI를 사용하여 앱을 빌드 및 배포합니다.

아래는 Expo CLIEAS CLI의 주요 역할을 정리한 표입니다:

작업 expo-cli eas-cli

로컬에서 앱 실행 및 테스트 ✅ (expo start)
앱 빌드 ⚠️ (Deprecated, 사용 비권장) ✅ (스토어 배포 가능)
스토어에 앱 배포 ✅ (eas submit)
OTA 업데이트 ⚠️ (기본적인 업데이트만 가능) ✅ (eas update로 더 세부적 관리 가능)
Bare Workflow 지원 ✅ (Managed와 Bare 둘 다 지원)

EAS CLI 설치

Expo 프로젝트를 생성한 후, 다음 명령어를 통해 EAS CLI를 설치합니다

npm install -g eas-cli

EAS CLI 로그인

다음 명령어로 프로젝트를 초기화합니다

eas init

실행 예시는 다음과 같습니다

√ Would you like to create a project for @userId/projectName? ... yes
✔ Created @userId/projectName: <https://expo.dev/accounts/userId/projects/projectName>
√ Project successfully linked (ID: ID Number) (modified app.json)

필자는 Expo 계정을 이미 보유하고 있었기에 위와 같이 프로젝트가 생성되었습니다

로그인

eas login

로그인이 성공하면 프로젝트가 Expo 계정에 연결됩니다.

웹사이트 https://expo.dev/ 에 접속하면 프로젝트가 생성된 것을 확인할 수 있습니다

라우트 설정

기본 설정

Expo에서는 파일 기반 라우팅을 사용합니다. 기본적으로 app 폴더 내에서 라우팅이 이루어집니다.

특히 app/_layout.tsx 파일은 프로젝트의 레이아웃을 정의하며, 공통 UI 요소(헤더, 네비게이션 등)를 설정할 수 있습니다.


주요 기능

  1. 공통 레이아웃 제공
  2. _layout.tsx는 특정 경로에 속하는 모든 페이지에서 공통적으로 사용하는 레이아웃을 정의합니다.
  3. 페이지 간 탐색
  4. Expo Router를 사용해 페이지 이동 및 탐색 기록을 쉽게 관리할 수 있습니다.

스택 네비게이터 설치

스택 네비게이터는 화면 간 전환과 탐색 기록 관리를 지원합니다. 다음 패키지를 설치합니다

npx expo install expo-router react-native-safe-area-context react-native-screens expo-linking expo-constants expo-status-bar

사용 예제

  • index.tsx
export default function HomeScreen() {
  return (
    <View>
      <Text>app/index 페이지</Text>
      <Link href={"/diary"}>app/diary/index로 이동하기</Link>
      <Pressable onPress={() => router.push("/diary/details")}>
        <Text>app/diary/details로 이동하기</Text>
      </Pressable>
    </View>
  );
}

위처럼 Link와 router.push같은 방법으로 이동 할 수 있습니다.

/diary 라고 했을 때 diary폴더 안의 index.tsx를 찾아가고 /diary/details라고 했을 때는 diary폴더 안의 details 파일로 이동합니다.

  • _layout.tsx
 	return (
    <ThemeProvider value={colorScheme === "dark" ? DarkTheme : DefaultTheme}>
      <Stack
        screenOptions={{
          headerStyle: {
            backgroundColor: "#f4511e",
          },
          headerTintColor: "#fff",
          headerTitleStyle: {
            fontWeight: "bold",
          },
        }}
      >
        <Stack.Screen
          name="index"
          options={{
            title: "Main Screen", // index.tsx의 기본 이름을 변경
          }}
        />
        <Stack.Screen name="(tabs)" options={{ headerShown: false }} />
        <Stack.Screen name="+not-found" />
      </Stack>
      <StatusBar style="auto" />
    </ThemeProvider>
  );
}

기본적으로 Stack.Screen에 등록을 하지 않아도 이동이 되지만 아래의 이유때문에 사용을 합니다.

  • 라우트 등록 이유
  • 명시적 제어 및 추가 설정을 위해 필요합니다.
  • 폴더 구조 및 관리
  • 기능별로 라우트를 폴더 단위로 분리하고, 각 폴더 내 _layout.tsx 파일을 활용하면 효율적으로 관리할 수 있습니다.