Skip to content

thetentmaker/react-native-cli

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

8 Commits
 
 
 
 

Repository files navigation

React Native CLI 학습 정리

React Native CLI를 중심으로 모바일 앱 개발에 필요한 핵심 개념과 실무 팁을 정리한 초안입니다.

1) React Native CLI에 대해서

1-1. React Native CLI란?

  • Facebook(현 Meta)이 만든 크로스플랫폼 프레임워크인 React Native를 순정(베어) 환경에서 사용하는 명령줄 도구입니다.
  • iOS/Android의 네이티브 프로젝트 구조를 그대로 생성하고, Xcode/Android Studio와 긴밀하게 연동됩니다.
  • Expo와 달리 네이티브 코드 수준의 커스터마이징(플러그인, 네이티브 모듈, 빌드 설정 변경 등)에 제약이 적습니다.
react-native log-android
react-native log-ios

1-2. React Native CLI 설정하기

brew install node # npm, npx 포함
brew install watchman # 파일 시스템 감시 도구(file watcher), 파일이 변경되었는지 실시간으로 감지해주는 툴
brew install ruby # pod install 명령이 ruby 스크립트로 실행
brew install ruby-build # 루비 버전을 설치해주는 도구로 rbenv와 함께 사용됨
brew install rbenv # 루비 버전 관리를 위함
  • iOS 설정 확인:
    • Xcode 설치, Command Line Tools 설정
  • AND 설정 확인:
export ANDROID_HOME=$HOME/Library/Android/sdk
export PATH=$PATH:$ANDROID_HOME/emulator
export PATH=$PATH:$ANDROID_HOME/platform-tools
  • 프로젝트 생성:
npx react-native init FirstProject
  • ios pod 설치: 의존설 관리 도구
cd ios && pod install 
  • 실행
npm run ios

1-3. Expo와의 차이점

  • Expo: 빠른 시작, OTA 업데이트, 풍부한 SDK, 관리형/베어 워크플로우 제공. 단, 일부 네이티브 커스터마이징은 제한될 수 있음(관리형 기준).
  • React Native CLI: 초기 설정은 더 수고롭지만, 네이티브 레벨 변경에 유연. 대규모/커스텀 네이티브 요구사항에 유리.
  • 팀/프로젝트 요구사항에 따라 선택하거나, Expo Bare로 전환/혼합 전략도 가능.

1-4. 새로운 Dependency Manager 소개

  • AND: gradle
    • build.gradle
  • iOS: cocoapods
    • Podfile

1-5. 디버그 도구 Flipper 소개

  • Flipper
    • Layout Inspector
    • React DevTools
    • Images
    • Database
  • React-Native-Debugger
  • 등 여러가지 Debugging Tool이 있고 각자의 스타일에 따라 사용

2) AND/iOS에서 반드시 알아야 할 개념

2-1. Android

  • AndroidManifest.xml: 앱의 권한, 액티비티, 서비스, 딥링크, 최소 SDK 등 메타데이터 선언 파일.
  • Activity: 화면 단위의 컴포넌트. RN는 기본 Activity 위에 ReactRootView를 올려 RN UI를 렌더링합니다.
  • Application: 앱 전역 초기화 지점, 네이티브 모듈 초기화, 디버그 설정 등을 배치.

2-2. iOS

  • AppDelegate: 앱 생명주기 진입점, 푸시/딥링크 등 핸들링.
  • Info.plist: 번들 메타데이터(권한 설명, URL Scheme, 설정 키 등)를 선언하는 파일.
  • Build Phase: 빌드 시 실행되는 단계별 작업들로, 소스코드를 앱으로 변환하는 과정을 자동화하는 스크립트 모음

2-3. Permissions(권한)

  • AND: Manifest에 권한 선언 + 런타임 권한 요청 필요 (위험 권한의 경우). 사용자가 거부해도 앱은 반복해서 권한 요청 가능. 단, "다시 묻지 않음"을 선택하면 시스템 다이얼로그는 나타나지 않고, 설정으로 유도해야 함.
  • iOS: Info.plist에 권한 설명 키 (NSCameraUsageDescription 등) 필수. 최초 1회 권한 요청만 시스템이 다이얼로그로 처리. 사용자가 거부하면, 이후 재요청해도 시스템 다이얼로그는 다시 뜨지 않음.
  • RN에서는 react-native-permissions 등의 라이브러리를 통해 두 플랫폼의 권한 요청 흐름을 통합할 수 있음

2-4. Scheme(스킴)

  • URL Scheme/Universal Links(App Links)를 통해 외부에서 앱을 열거나 특정 화면으로 동.
  • iOS: Info.plist URL Types 설정, Android: Manifest intent-filter 설정 필요.
  • scheme 테스트:
npx uri-scheme open "scheme://path" --ios
npx uri-scheme open "scheme://path" --android

3) Native Module이 뭔가요?

3-1. React Native가 동작하는 원리(개요)

React Native 에서 다루는 Thread

  • JavaScript 스레드와 네이티브(UI/메인) 스레드가 브리지 또는 JSI를 통해 상호작용합니다.
  • JS에서 네이티브 기능(카메라, 센서 등)을 호출하고, 네이티브는 결과를 JS로 전달합니다.
- MainThread: 네이티브 UI를 그려주고, 사용자 입력을 처리하는 역할
- Javascript Thread: 작성한 JS 코드를 실행하고 로직을 처리하는 역할
- Native Module Thread: JS에서 호출된 네이티브 모듈을 처리하는 역할
- Shadow Thread: 레이아웃 계산 (Yoga 엔진 사용), 실제 레이아웃 정보가 계산되면 Main Thread에 전달되어 UI가 그려짐
sequenceDiagram
    participant User
    participant OS
    participant MainThread as Main Thread<br/>(UI Thread)
    participant JSThread as JavaScript Thread
    participant ShadowThread as Shadow Thread
    participant YogaEngine as Yoga Layout Engine

    User->>OS: 앱 아이콘 터치
    OS->>MainThread: 앱 프로세스 시작
    MainThread->>MainThread: 초기 화면 준비
    MainThread->>JSThread: JavaScript 번들 로드<br/>(index.js, App.js)
    
    Note over JSThread: React 컴포넌트 로직 실행
    JSThread->>JSThread: React Element Tree 생성
    JSThread->>JSThread: Diffing 작업 수행
    
    JSThread->>ShadowThread: 변경된 트리 구조 전달
    ShadowThread->>YogaEngine: 레이아웃 계산 요청
    YogaEngine->>ShadowThread: Shadow Node Tree 생성
    
    ShadowThread->>MainThread: 레이아웃 정보 전달
    MainThread->>MainThread: 네이티브 UI 컴포넌트<br/>생성/업데이트
    MainThread->>User: 화면에 UI 표시
Loading

3-2. Native Module이란?

  • JS에서 접근할 수 있도록 네이티브 기능을 래핑한 모듈입니다.
  • iOS(Objective-C/Swift), Android(Java/Kotlin)로 구현하며, JS/TS로 공개 API를 제공합니다.

3-3. New Architecture(새 아키텍처)

  • Fabric(UI 레이어)와 TurboModules(네이티브 모듈) + JSI 기반으로 브리지 의존도를 낮추고 성능/타입 안전성 개선을 지향합니다.
  • Codegen을 통해 네이티브-JS 인터페이스를 자동 생성하여 일관성 및 유지보수성을 높입니다.

  • [AS-IS:
[JS Thread]
   |
  (JSON)
   |
[Bridge]  ← 느림 / 비동기 / 병목
   |
  (JSON)
   |
[Native Thread]
  • TO-BE
JS Thread  <-> JSI (C++) ⇄ Native Code
동기 / 빠름 / 직렬화 없음

TurboModules(새로운 네이티브 모듈 시스템)

// 기존 방식
import { NativeModules } from 'react-native';
const { CameraModule } = NativeModules;

// TurboModules 방식
import { TurboModuleRegistry } from 'react-native';
const CameraModule = TurboModuleRegistry.get('CameraModule');

Fabric(새로운 렌더링 시스템)

기존: JavaScript → Bridge → Shadow Thread → Main Thread

새로운: JavaScript → JSI → Fabric → Main Thread

3-4. Hermes

모바일에 특화된 빠르고 가벼운 JavaScript 엔진

  • 도입 이전
    • App 실행 -> JS파싱 -> 컴파일 -> 실행
    • 런타임에 Javascript 파싱 및 컴파일
  • 도입 이후
    • 빌드 시점 -> 바이트코드 생성 -> 앱 실행 시 바로 실행
  • 개선효과
    • 앱 시작 시간 단축
    • 메모리 사용량 감소
    • 더 작은 번들 사이즈(Android)

추가 학습

React Native에서 == vs === 비교 연산자

React Native에서 값을 비교할 때 사용하는 두 가지 연산자의 차이점을 알아보겠습니다.

== (동등 연산자, Loose Equality)

타입 변환을 수행한 후 값을 비교합니다. 서로 다른 타입의 값도 같다고 판단할 수 있습니다.

예시

5 == "5"          // true (문자열 "5"를 숫자 5로 변환)
true == 1         // true (true를 1로 변환)
false == 0        // true (false를 0으로 변환)
null == undefined // true
"" == 0           // true (빈 문자열을 0으로 변환)

=== (일치 연산자, Strict Equality)

타입 변환 없이 값과 타입을 모두 비교합니다. 값과 타입이 모두 같아야 true를 반환합니다.

예시

5 === "5"         // false (타입이 다름: number vs string)
true === 1        // false (타입이 다름: boolean vs number)
false === 0       // false (타입이 다름: boolean vs number)
null === undefined // false (타입이 다름)
"" === 0          // false (타입이 다름: string vs number)
5 === 5           // true (값과 타입 모두 같음)

권장사항

React Native 개발에서는 ===를 사용하는 것을 강력히 권장합니다.

이유

  1. 예측 가능한 동작: 타입 변환으로 인한 예상치 못한 결과를 방지
  2. 성능: 타입 변환 과정이 없어 더 빠름
  3. 코드 품질: 더 명확하고 안전한 코드 작성 가능

좋은 예시 (===)

if (userInput === "") {
  // 빈 문자열인 경우만 처리
}

if (count === 0) {
  // 숫자 0인 경우만 처리
}

피해야 할 예시 (==)

if (userInput == 0) {
  // "0", "", false 등 다양한 값이 true가 될 수 있음
  // 예상치 못한 동작을 유발할 수 있음
}

결론

React Native에서는 의도치 않은 타입 변환을 피하고 더 안전한 코드를 작성하기 위해 ===를 사용하는 것이 좋습니다.

About

No description, website, or topics provided.

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published