React Native Complete Guide | Mobile Apps with JavaScript
이 글의 핵심
React Native lets you build native iOS and Android apps using React and JavaScript. This guide covers the full development workflow ??from Expo setup to navigation, state management, and native device APIs.
What This Guide Covers
React Native lets you write one JavaScript codebase that compiles to native iOS and Android apps. This guide covers the Expo workflow, core components, navigation, hooks, and native device APIs.
Real-world insight: A team of three web developers shipped an iOS and Android app in six weeks using React Native + Expo ??they leveraged 80% of their existing React knowledge from day one.
Setup with Expo
npx create-expo-app MyApp --template blank-typescript
cd MyApp
npx expo start
Scan the QR code with the Expo Go app on your phone, or press i/a to open iOS Simulator / Android Emulator.
1. Core Components
React Native uses platform-native components instead of HTML:
| HTML | React Native |
|---|---|
<div> | <View> |
<p>, <span> | <Text> |
<img> | <Image> |
<input> | <TextInput> |
<button> | <TouchableOpacity> or <Pressable> |
<ul> | <FlatList> or <ScrollView> |
import { View, Text, Image, Pressable, StyleSheet } from 'react-native';
export function ProfileCard({ user }) {
return (
<View style={styles.card}>
<Image source={{ uri: user.avatar }} style={styles.avatar} />
<Text style={styles.name}>{user.name}</Text>
<Pressable style={styles.button} onPress={() => alert('Follow!')}>
<Text style={styles.buttonText}>Follow</Text>
</Pressable>
</View>
);
}
const styles = StyleSheet.create({
card: { padding: 16, backgroundColor: '#fff', borderRadius: 12 },
avatar: { width: 64, height: 64, borderRadius: 32 },
name: { fontSize: 18, fontWeight: '600', marginTop: 8 },
button: { backgroundColor: '#007AFF', padding: 12, borderRadius: 8, marginTop: 12 },
buttonText: { color: '#fff', textAlign: 'center', fontWeight: '600' },
});
2. Layout with Flexbox
React Native uses Flexbox for layout ??same as CSS, but flexDirection defaults to column instead of row:
<View style={{ flex: 1, flexDirection: 'row', justifyContent: 'space-between', alignItems: 'center' }}>
<Text>Left</Text>
<Text>Right</Text>
</View>
// Full-screen centered content
<View style={{ flex: 1, justifyContent: 'center', alignItems: 'center' }}>
<Text>Centered</Text>
</View>
3. Lists
FlatList (large lists)
import { FlatList, Text, View } from 'react-native';
const DATA = [
{ id: '1', title: 'Item One' },
{ id: '2', title: 'Item Two' },
];
<FlatList
data={DATA}
keyExtractor={(item) => item.id}
renderItem={({ item }) => (
<View style={{ padding: 16, borderBottomWidth: 1, borderColor: '#eee' }}>
<Text>{item.title}</Text>
</View>
)}
onEndReached={loadMoreData}
onEndReachedThreshold={0.5}
refreshing={isRefreshing}
onRefresh={handleRefresh}
/>
SectionList (grouped lists)
<SectionList
sections={[
{ title: 'Today', data: todayItems },
{ title: 'Yesterday', data: yesterdayItems },
]}
keyExtractor={(item) => item.id}
renderItem={({ item }) => <Text>{item.title}</Text>}
renderSectionHeader={({ section }) => (
<Text style={{ fontWeight: 'bold', padding: 8 }}>{section.title}</Text>
)}
/>
4. Navigation with React Navigation
npx expo install @react-navigation/native @react-navigation/native-stack
npx expo install react-native-screens react-native-safe-area-context
import { NavigationContainer } from '@react-navigation/native';
import { createNativeStackNavigator } from '@react-navigation/native-stack';
const Stack = createNativeStackNavigator();
export default function App() {
return (
<NavigationContainer>
<Stack.Navigator initialRouteName="Home">
<Stack.Screen name="Home" component={HomeScreen} />
<Stack.Screen name="Detail" component={DetailScreen} options={{ title: 'Post' }} />
</Stack.Navigator>
</NavigationContainer>
);
}
// Navigate and pass params
function HomeScreen({ navigation }) {
return (
<Pressable onPress={() => navigation.navigate('Detail', { postId: '123' })}>
<Text>Go to Detail</Text>
</Pressable>
);
}
// Read params
function DetailScreen({ route }) {
const { postId } = route.params;
return <Text>Post: {postId}</Text>;
}
Tab Navigation
import { createBottomTabNavigator } from '@react-navigation/bottom-tabs';
const Tab = createBottomTabNavigator();
<Tab.Navigator>
<Tab.Screen name="Home" component={HomeScreen} />
<Tab.Screen name="Profile" component={ProfileScreen} />
<Tab.Screen name="Settings" component={SettingsScreen} />
</Tab.Navigator>
5. Native Device APIs (Expo)
npx expo install expo-camera expo-location expo-notifications
Camera
import { CameraView, useCameraPermissions } from 'expo-camera';
export function CameraScreen() {
const [permission, requestPermission] = useCameraPermissions();
if (!permission?.granted) {
return <Pressable onPress={requestPermission}><Text>Allow Camera</Text></Pressable>;
}
return <CameraView style={{ flex: 1 }} facing="back" />;
}
Location
import * as Location from 'expo-location';
const [status] = await Location.requestForegroundPermissionsAsync();
if (status !== 'granted') return;
const location = await Location.getCurrentPositionAsync({});
console.log(location.coords.latitude, location.coords.longitude);
AsyncStorage (persistence)
npx expo install @react-native-async-storage/async-storage
import AsyncStorage from '@react-native-async-storage/async-storage';
await AsyncStorage.setItem('user', JSON.stringify(user));
const stored = await AsyncStorage.getItem('user');
const user = stored ? JSON.parse(stored) : null;
6. State Management
For simple state: useState + useContext. For complex state: Zustand or Redux Toolkit.
// Zustand store
import { create } from 'zustand';
import { persist, createJSONStorage } from 'zustand/middleware';
import AsyncStorage from '@react-native-async-storage/async-storage';
const useAuthStore = create(
persist(
(set) => ({
user: null,
setUser: (user) => set({ user }),
logout: () => set({ user: null }),
}),
{
name: 'auth-storage',
storage: createJSONStorage(() => AsyncStorage),
}
)
);
7. Styling Patterns
import { StyleSheet, useColorScheme } from 'react-native';
// Dynamic styles for dark mode
function ThemedCard() {
const colorScheme = useColorScheme(); // 'light' | 'dark'
const styles = StyleSheet.create({
card: {
backgroundColor: colorScheme === 'dark' ? '#1c1c1e' : '#ffffff',
padding: 16,
borderRadius: 12,
},
text: {
color: colorScheme === 'dark' ? '#ffffff' : '#000000',
},
});
return <View style={styles.card}><Text style={styles.text}>Card</Text></View>;
}
Production Build with EAS
npm install -g eas-cli
eas login
eas build:configure
# Build for iOS and Android
eas build --platform all
# Submit to App Store and Play Store
eas submit --platform all
Key Takeaways
| Topic | Key point |
|---|---|
| Components | View/Text/Image/Pressable replace HTML elements |
| Layout | Flexbox, column by default |
| Lists | FlatList for performance, SectionList for grouping |
| Navigation | React Navigation ??stack, tab, drawer |
| Native APIs | Expo modules for camera, location, notifications |
| Persistence | AsyncStorage for simple key-value, SQLite for structured |
| Build | Expo Application Services (EAS) for store submissions |
Start with Expo’s managed workflow, learn the core components, then add navigation. The React knowledge you already have transfers directly ??the main shift is thinking in native components and mobile UX patterns.
?�주 묻는 질문 (FAQ)
Q. ???�용???�무?�서 ?�제 ?�나??
A. Build iOS and Android apps with React Native. Covers core components, navigation, state management, native APIs, and Exp???�무?�서????본문???�제?� ?�택 가?�드�?참고???�용?�면 ?�니??
Q. ?�행?�로 ?�으�?좋�? 글?�?
A. �?글 ?�단???�전 글 ?�는 관??글 링크�??�라가�??�서?��?배울 ???�습?�다. C++ ?�리�?목차?�서 ?�체 ?�름???�인?????�습?�다.
Q. ??깊이 공�??�려�?
A. cppreference?� ?�당 ?�이브러�?공식 문서�?참고?�세?? 글 말�???참고 ?�료 링크???�용?�면 좋습?�다.
같이 보면 좋�? 글 (?��? 링크)
??주제?� ?�결?�는 ?�른 글?�니??
- [React 18 Deep Dive | Concurrent Features· Suspense](/en/blog/react-18-deep-dive/
- [TypeScript 5 Complete Guide | Decorators· satisfies](/en/blog/typescript-5-complete-guide/
??글?�서 ?�루???�워??(관??검?�어)
React Native, Mobile, iOS, Android, Expo, JavaScript ?�으�?검?�하?�면 ??글???��????�니??