소프트웨어 기술(스타트업 위주)
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
는 레이아웃을 구성하는 기본적인 컨테이너입니다. 여기에는 SafeAreaView
와 KeyboardAvoidingView
같은 확장된 컴포넌트도 포함됩니다.
- 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: '이것은 로컬 푸시 알림입니다.',
})