소프트웨어 기술(스타트업 위주)

react-native

react-native 정리 입니다. 추가적인 자세한 설명 및 툴 이용 방법은 각 목차별로 공식문서 페이지로 하이퍼링크 참조하겠습니다.


1. React Native란?

React Native는 Facebook(현재 Meta)이 개발한 오픈소스 모바일 애플리케이션 프레임워크로, React를 기반으로 하여 iOS 및 Android 애플리케이션을 개발할 수 있도록 지원합니다. 하나의 코드베이스로 두 개의 주요 모바일 플랫폼에서 실행되는 애플리케이션을 만들 수 있어 개발 생산성을 크게 향상시킵니다.

1.1 왜 React Native를 사용할까?

  • 크로스 플랫폼 개발: 하나의 코드베이스로 iOS와 Android 앱을 동시에 개발할 수 있습니다.
  • 핫 리로딩 (Hot Reloading): 코드 변경 사항을 즉시 반영할 수 있어 개발 속도가 빠릅니다.
  • 네이티브 성능: 네이티브 API와의 직접적인 연동을 통해 높은 성능을 제공합니다.
  • 커뮤니티 지원: React와 같은 광범위한 개발자 커뮤니티가 있으며, 오픈소스 패키지가 풍부합니다.
  • 코드 재사용성: 웹과 모바일 간 코드 재사용이 가능하여 개발 효율성이 높아집니다.
  • 코드 푸쉬 : 코드푸쉬 기능

1.2 React Native 대안

React Native 외에도 크로스 플랫폼 개발을 지원하는 다양한 프레임워크가 있습니다.

  • Flutter: Google이 개발한 프레임워크로, Dart 언어를 사용하며 높은 성능과 풍부한 UI 컴포넌트를 제공합니다.
  • Xamarin: Microsoft에서 개발한 C# 기반 프레임워크로, 강력한 네이티브 기능을 지원합니다.
  • Ionic: HTML, CSS, JavaScript 기반의 하이브리드 앱 프레임워크로, 웹 기술을 활용하여 모바일 앱을 개발할 수 있습니다.

2. 환경 설정

2.1 React Native CLI 설치

React Native를 설치하려면 먼저 Node.js, npm 또는 yarn이 필요합니다.

설치 방법 (macOS/Linux 기준)

# Node.js 설치 (설치되어 있지 않은 경우)
brew install node

# React Native CLI 설치
yarn global add react-native-cli

Windows에서는 choco install nodejs 또는 scoop install nodejs를 사용하여 Node.js를 설치한 후, npm install -g react-native-cli 명령어를 실행하면 됩니다.

2.2 Metro Bundler

Metro는 React Native의 기본 번들러로, JavaScript 코드를 번들링하고 최적화하여 앱에서 실행할 수 있도록 변환하는 역할을 합니다. React Native 프로젝트를 실행하면 자동으로 Metro가 실행됩니다.

# 프로젝트 생성
npx react-native init MyApp

# 프로젝트 디렉토리 이동
cd MyApp

# Metro 실행
npx react-native start

3. 개발 워크플로우

3.1 디바이스에서 실행하기

iOS에서 실행

npx react-native run-ios

위 명령어를 실행하면 Xcode 시뮬레이터에서 앱이 실행됩니다.

Android에서 실행

npx react-native run-android

위 명령어를 실행하면 Android 에뮬레이터 또는 실제 기기에서 앱이 실행됩니다.

3.2 디버깅

3.2.1 In-App Developer Menu

디버깅을 위해 개발자 메뉴를 열 수 있습니다.

  • Android: Cmd + M (Mac) 또는 Ctrl + M (Windows)
  • iOS: Cmd + D

3.2.2 Fast Refresh 활성화

Fast Refresh를 사용하면 코드 변경 사항이 즉시 반영됩니다. 기본적으로 활성화되어 있으며, 필요 시 개발자 메뉴에서 토글할 수 있습니다.

npx react-native start --reset-cache

3.2.3 LogBox

React Native의 오류 및 경고 메시지를 확인할 수 있는 UI 기반 디버깅 도구입니다. 콘솔에서 console.log, console.warn, console.error를 사용하면 LogBox에서 메시지를 확인할 수 있습니다.

console.log('디버깅 메시지 출력')
console.warn('경고 메시지')
console.error('오류 메시지')

3.2.4 Sourcemaps 사용

Sourcemaps를 사용하면 변환된 코드 대신 원본 코드를 기반으로 디버깅할 수 있습니다. Chrome DevTools에서 Enable sourcemaps 옵션을 활성화하면 사용 가능합니다.

3.2.5 React Native DevTools

React Native DevTools는 상태, 네트워크 요청, 퍼포먼스 등을 시각적으로 확인할 수 있는 도구입니다.

npx react-devtools

실행 후 DevTools에서 상태 관리와 UI 렌더링 과정을 모니터링할 수 있습니다.


4. React Native 핵심 컴포넌트

React Native에서 자주 사용되는 핵심 컴포넌트들을 정리하고, 각각의 설명과 예제 코드를 제공합니다.

4.1 텍스트 (Text)

개요

Text 컴포넌트는 화면에 텍스트를 표시할 때 사용됩니다.

사용법 예제

import React from 'react'
import { Text, View } from 'react-native'

const App = () => {
  return (
    <View>
      <Text>안녕하세요, React Native!</Text>
    </View>
  )
}

export default App

4.2 텍스트 입력 (TextInput)

개요

TextInput은 사용자가 텍스트를 입력할 수 있는 입력 필드를 제공합니다.

사용법 예제

import React, { useState } from 'react'
import { TextInput, View, Text } from 'react-native'

const App = () => {
  const [text, setText] = useState('')
  return (
    <View>
      <TextInput
        placeholder="텍스트를 입력하세요"
        value={text}
        onChangeText={setText}
        style={{ borderBottomWidth: 1, marginBottom: 10 }}
      />
      <Text>입력한 텍스트: {text}</Text>
    </View>
  )
}

export default App

4.3 버튼 (Button)

개요

Button 컴포넌트는 기본적인 버튼을 제공합니다.

사용법 예제

import React from 'react'
import { Button, View, Alert } from 'react-native'

const App = () => {
  return (
    <View>
      <Button title="클릭하세요" onPress={() => Alert.alert('버튼 클릭됨!')} />
    </View>
  )
}

export default App

4.4 이미지 (Image)

개요

Image 컴포넌트는 이미지를 표시하는 데 사용됩니다.

사용법 예제

import React from 'react'
import { Image, View } from 'react-native'

const App = () => {
  return (
    <View>
      <Image
        source={{ uri: 'https://reactnative.dev/img/tiny_logo.png' }}
        style={{ width: 50, height: 50 }}
      />
    </View>
  )
}

export default App

4.5 이미지 배경 (ImageBackground)

개요

ImageBackground는 배경으로 이미지를 사용할 때 사용됩니다.

사용법 예제

import React from 'react'
import { ImageBackground, Text, View } from 'react-native'

const App = () => {
  return (
    <ImageBackground
      source={{ uri: 'https://reactnative.dev/img/tiny_logo.png' }}
      style={{ width: '100%', height: '100%' }}
    >
      <Text style={{ color: 'white' }}>배경 이미지 위의 텍스트</Text>
    </ImageBackground>
  )
}

export default App

4.6 스위치 (Switch)

개요

Switch 컴포넌트는 토글 기능을 제공하는 UI 요소입니다.

사용법 예제

import React, { useState } from 'react'
import { Switch, View, Text } from 'react-native'

const App = () => {
  const [isEnabled, setIsEnabled] = useState(false)
  return (
    <View>
      <Switch value={isEnabled} onValueChange={setIsEnabled} />
      <Text>{isEnabled ? '켜짐' : '꺼짐'}</Text>
    </View>
  )
}

export default App

4.7 상태 바 (StatusBar)

개요

StatusBar는 상태 표시줄의 스타일을 설정하는 데 사용됩니다.

사용법 예제

import React from 'react'
import { StatusBar, View } from 'react-native'

const App = () => {
  return (
    <View>
      <StatusBar barStyle="dark-content" backgroundColor="#fff" />
    </View>
  )
}

export default App

4.8 활동 표시기 (ActivityIndicator)

개요

ActivityIndicator는 로딩 상태를 표시할 때 사용됩니다.

사용법 예제

import React from 'react'
import { ActivityIndicator, View } from 'react-native'

const App = () => {
  return (
    <View>
      <ActivityIndicator size="large" color="#0000ff" />
    </View>
  )
}

export default App

4.9 모달 (Modal)

개요

Modal은 팝업 창을 표시하는 데 사용됩니다.

사용법 예제

import React, { useState } from 'react'
import { Modal, View, Text, Button } from 'react-native'

const App = () => {
  const [visible, setVisible] = useState(false)
  return (
    <View>
      <Button title="모달 열기" onPress={() => setVisible(true)} />
      <Modal visible={visible} transparent>
        <View
          style={{
            flex: 1,
            justifyContent: 'center',
            alignItems: 'center',
            backgroundColor: 'rgba(0,0,0,0.5)',
          }}
        >
          <View style={{ backgroundColor: 'white', padding: 20 }}>
            <Text>모달 내용</Text>
            <Button title="닫기" onPress={() => setVisible(false)} />
          </View>
        </View>
      </Modal>
    </View>
  )
}

export default App

4.10 Pressable

Pressable 컴포넌트는 사용자의 입력(터치, 클릭 등)에 반응하는 요소를 만들 때 사용됩니다. TouchableOpacity, TouchableHighlight 등의 기존 터치 관련 컴포넌트보다 더 유연한 제스처 및 상태 관리를 제공합니다.

사용 예시

import React, { useState } from 'react'
import { Pressable, Text, View } from 'react-native'

const App = () => {
  const [pressed, setPressed] = useState(false)

  return (
    <View style={{ flex: 1, justifyContent: 'center', alignItems: 'center' }}>
      <Pressable
        onPress={() => setPressed(!pressed)}
        style={({ pressed }) => [
          {
            backgroundColor: pressed ? 'lightgray' : 'blue',
            padding: 10,
            borderRadius: 5,
          },
        ]}
      >
        <Text style={{ color: 'white', fontSize: 16 }}>
          {pressed ? '눌렀어요!' : '눌러보세요'}
        </Text>
      </Pressable>
    </View>
  )
}

export default App

4.11 View

View는 레이아웃을 구성하는 기본적인 컨테이너입니다. 여기에는 SafeAreaViewKeyboardAvoidingView 같은 확장된 컴포넌트도 포함됩니다.

  • SafeAreaView SafeAreaView는 iOS에서 화면 상단의 노치(Notch)와 하단의 홈 인디케이터를 피하도록 도와주는 컴포넌트입니다.

사용 예시

import React from 'react'
import { SafeAreaView, Text } from 'react-native'

const App = () => {
  return (
    <SafeAreaView
      style={{ flex: 1, justifyContent: 'center', alignItems: 'center' }}
    >
      <Text>안전 영역 내에서 렌더링</Text>
    </SafeAreaView>
  )
}

export default App
  • KeyboardAvoidingView KeyboardAvoidingView는 키보드가 화면을 가릴 경우 자동으로 조정하여 UI가 보이도록 하는 컴포넌트입니다.

사용 예시

import React, { useState } from 'react'
import {
  KeyboardAvoidingView,
  TextInput,
  Button,
  Platform,
  View,
} from 'react-native'

const App = () => {
  const [text, setText] = useState('')

  return (
    <KeyboardAvoidingView
      behavior={Platform.OS === 'ios' ? 'padding' : 'height'}
      style={{ flex: 1, justifyContent: 'center', alignItems: 'center' }}
    >
      <TextInput
        value={text}
        onChangeText={setText}
        placeholder="입력하세요"
        style={{ borderWidth: 1, padding: 10, width: 200 }}
      />
      <Button title="제출" onPress={() => alert(text)} />
    </KeyboardAvoidingView>
  )
}

export default App

4.12 Listings

리스트를 표현하는 다양한 방법을 설명합니다.

ScrollView ScrollView는 스크롤이 가능한 뷰를 제공합니다. 한 번에 많은 데이터를 렌더링하면 성능 문제가 발생할 수 있으므로, 적은 양의 데이터에 적합합니다.

사용 예시

import React from 'react'
import { ScrollView, Text, View } from 'react-native'

const App = () => {
  return (
    <ScrollView>
      {Array.from({ length: 20 }, (_, i) => (
        <View key={i} style={{ padding: 20, borderBottomWidth: 1 }}>
          <Text>{`아이템 ${i + 1}`}</Text>
        </View>
      ))}
    </ScrollView>
  )
}

export default App

List Views

  • FlatList FlatList는 대량의 데이터를 렌더링할 때 성능 최적화가 적용된 리스트입니다.

사용 예시

import React from 'react'
import { FlatList, Text, View } from 'react-native'

const DATA = Array.from({ length: 50 }, (_, i) => ({
  id: i.toString(),
  title: `아이템 ${i + 1}`,
}))

const App = () => {
  return (
    <FlatList
      data={DATA}
      keyExtractor={(item) => item.id}
      renderItem={({ item }) => (
        <View style={{ padding: 20, borderBottomWidth: 1 }}>
          <Text>{item.title}</Text>
        </View>
      )}
    />
  )
}

export default App

SectionList SectionList는 데이터를 섹션별로 그룹화하여 리스트를 렌더링할 때 사용됩니다.

사용 예시

import React from 'react'
import { SectionList, Text, View } from 'react-native'

const DATA = [
  {
    title: 'A 섹션',
    data: ['Apple', 'Avocado'],
  },
  {
    title: 'B 섹션',
    data: ['Banana', 'Blueberry'],
  },
]

const App = () => {
  return (
    <SectionList
      sections={DATA}
      keyExtractor={(item, index) => item + index}
      renderItem={({ item }) => (
        <View style={{ padding: 20, borderBottomWidth: 1 }}>
          <Text>{item}</Text>
        </View>
      )}
      renderSectionHeader={({ section: { title } }) => (
        <Text style={{ fontSize: 18, fontWeight: 'bold', padding: 10 }}>
          {title}
        </Text>
      )}
    />
  )
}

export default App
  • RefreshControl RefreshControl을 사용하면 ScrollView 또는 FlatList에서 당겨서 새로고침(Pull-to-Refresh) 기능을 구현할 수 있습니다.

사용 예시

import React, { useState } from 'react'
import { ScrollView, RefreshControl, Text } from 'react-native'

const App = () => {
  const [refreshing, setRefreshing] = useState(false)

  const onRefresh = () => {
    setRefreshing(true)
    setTimeout(() => setRefreshing(false), 2000)
  }

  return (
    <ScrollView
      refreshControl={
        <RefreshControl refreshing={refreshing} onRefresh={onRefresh} />
      }
    >
      <Text style={{ padding: 20 }}>스크롤을 아래로 당겨 새로고침하세요!</Text>
    </ScrollView>
  )
}

export default App

5. 플랫폼별 코드 작성

5.1 platform 모듈

React Native에서는 Platform 모듈을 사용하여 iOS와 Android에서 서로 다른 코드를 실행할 수 있다.

import { Platform, Text } from 'react-native'

const PlatformSpecificText = () => {
  return (
    <Text>
      {Platform.OS === 'ios' ? '이것은 iOS입니다.' : '이것은 Android입니다.'}
    </Text>
  )
}

5.2 파일 확장자별 코드 분리

파일명을 .ios.js 또는 .android.js로 지정하면 자동으로 해당 플랫폼에 맞는 파일이 로드된다.

// MyComponent.ios.js
export default function MyComponent() {
  return <Text>iOS 전용 컴포넌트</Text>;
}

// MyComponent.android.js
export default function MyComponent() {
  return <Text>Android 전용 컴포넌트</Text>;
}

5.3 react-native-web

React Native 코드를 웹에서도 실행할 수 있도록 react-native-web을 사용할 수 있다.

설치:

npm install react-native-web

예제:

import { AppRegistry } from 'react-native'
import App from './App'
import { name as appName } from './app.json'
import { createRoot } from 'react-dom/client'

const rootElement = document.getElementById('root')
const root = createRoot(rootElement)
root.render(<App />)

AppRegistry.registerComponent(appName, () => App)

6. 스타일링

6.1 스타일시트

React Native에서는 StyleSheet API를 사용하여 스타일을 정의할 수 있다.

import { StyleSheet, Text, View } from 'react-native'

const styles = StyleSheet.create({
  container: {
    flex: 1,
    justifyContent: 'center',
    alignItems: 'center',
    backgroundColor: '#f0f0f0',
  },
  text: {
    fontSize: 20,
    fontWeight: 'bold',
    color: 'blue',
  },
})

export default function App() {
  return (
    <View style={styles.container}>
      <Text style={styles.text}>React Native 스타일링</Text>
    </View>
  )
}

6.2 레이아웃과 Flexbox

React Native는 CSS의 Flexbox 레이아웃 시스템을 활용한다.

import { View } from 'react-native'

const App = () => {
  return (
    <View
      style={{ flex: 1, flexDirection: 'row', justifyContent: 'space-around' }}
    >
      <View style={{ width: 50, height: 50, backgroundColor: 'red' }} />
      <View style={{ width: 50, height: 50, backgroundColor: 'green' }} />
      <View style={{ width: 50, height: 50, backgroundColor: 'blue' }} />
    </View>
  )
}

6.3 접근성 (Accessibility)

React Native는 접근성을 고려하여 accessibilityLabel 등의 속성을 제공한다.

import { Text, TouchableOpacity } from 'react-native'

export default function App() {
  return (
    <TouchableOpacity
      accessibilityLabel="버튼을 클릭하세요"
      onPress={() => alert('버튼 클릭됨!')}
    >
      <Text>클릭하세요</Text>
    </TouchableOpacity>
  )
}

이와 같은 방식으로 접근성을 강화할 수 있다.

7. 네트워킹

7.1 네트워크 연결 상태 확인

NetInfo 라이브러리를 사용하면 네트워크 상태를 확인할 수 있다.

설치:

npm install @react-native-community/netinfo

사용 예제:

import NetInfo from '@react-native-community/netinfo'

NetInfo.fetch().then((state) => {
  console.log('Is connected?', state.isConnected)
})

7.2 Fetch를 이용한 API 호출

React Native에서 fetch를 이용하여 API 요청을 보낼 수 있다.

fetch('https://jsonplaceholder.typicode.com/posts')
  .then((response) => response.json())
  .then((data) => console.log(data))
  .catch((error) => console.error(error))

7.3 WebSockets

WebSocket을 사용하여 실시간 데이터를 주고받을 수 있다.

const ws = new WebSocket('wss://example.com/socket')

ws.onopen = () => {
  ws.send('Hello Server!')
}

ws.onmessage = (event) => {
  console.log('Message from server: ', event.data)
}

8. 푸시 알림

React Native에서 푸시 알림을 구현하려면 react-native-push-notification 라이브러리를 사용할 수 있다.

설치:

npm install react-native-push-notification

예제:

import PushNotification from 'react-native-push-notification'

PushNotification.localNotification({
  title: '알림 제목',
  message: '이것은 로컬 푸시 알림입니다.',
})
Previous
FastAPI
Next
AWS