การพัฒนา Mobile App ในปี 2026 ไม่จำเป็นต้องเขียนแยก iOS และ Android อีกต่อไป React Native เป็น Cross-Platform Framework ยอดนิยมที่ใช้ JavaScript และ React ในการสร้างแอปมือถือที่มีประสิทธิภาพเทียบเท่า Native App และด้วย Expo ที่ช่วยให้เริ่มต้นได้ง่ายขึ้น ทำให้ React Native เป็นตัวเลือกอันดับหนึ่งสำหรับนักพัฒนาที่ต้องการสร้างแอปให้ทั้ง iOS และ Android จาก Codebase เดียวกัน
บทความนี้จะพาคุณเรียนรู้ React Native ตั้งแต่พื้นฐานจนถึงระดับที่สามารถสร้างแอปจริงและส่งขึ้น App Store ได้ ครอบคลุมทุกเรื่องสำคัญตั้งแต่ New Architecture, Expo, Navigation, State Management, Native Modules ไปจนถึง Push Notifications และ OTA Updates
React Native คืออะไร?
React Native คือ Open-Source Framework ที่สร้างโดย Meta (Facebook) สำหรับพัฒนา Mobile Application ด้วย JavaScript และ React โดยสิ่งที่ทำให้ React Native แตกต่างจาก Hybrid Framework อื่นๆ คือมันไม่ได้ใช้ WebView ในการ Render UI แต่จะ Render เป็น Native Component จริงๆ ทั้ง UIView ของ iOS และ android.view ของ Android
หลักการทำงานของ React Native คือ:
- JavaScript Thread: เขียน Logic และ UI ด้วย JavaScript/TypeScript
- Bridge/JSI: สื่อสารระหว่าง JavaScript กับ Native Code
- Native Thread: Render UI เป็น Native Component จริงๆ ของแต่ละ Platform
- Shadow Thread: คำนวณ Layout ด้วย Yoga (Flexbox Engine)
แอปที่สร้างด้วย React Native จะมี Look and Feel เหมือน Native App เพราะใช้ UI Component จริงของแต่ละ Platform ไม่ได้ใช้ HTML/CSS ใน WebView เหมือนพวก Cordova หรือ Ionic รุ่นเก่า
React Native vs Flutter vs Native: เปรียบเทียบ 2026
| คุณสมบัติ | React Native | Flutter | Native (Swift/Kotlin) |
|---|---|---|---|
| ภาษา | JavaScript / TypeScript | Dart | Swift (iOS) / Kotlin (Android) |
| Rendering | Native Components | Skia Engine (Custom Rendering) | Native Components |
| ประสิทธิภาพ | ใกล้เคียง Native (JSI) | ใกล้เคียง Native | ดีที่สุด |
| Hot Reload | Fast Refresh | Hot Reload | Swift Previews / Compose Preview |
| Code Sharing | iOS + Android + Web | iOS + Android + Web + Desktop | ไม่ได้ (แยก Codebase) |
| Community | ใหญ่มาก (React ecosystem) | ใหญ่ (Google backed) | ใหญ่มาก (Platform official) |
| Learning Curve | ง่ายถ้ารู้ React | ปานกลาง (ต้องเรียน Dart) | สูง (ต้องเรียนแยก 2 ภาษา) |
| UI Consistency | ตาม Platform (native look) | เหมือนกันทุก Platform | ตาม Platform |
| OTA Updates | รองรับ (Expo EAS Update) | จำกัด | ไม่รองรับ (ต้อง App Store) |
| Third-party Libraries | มากที่สุด (npm) | ปานกลาง (pub.dev) | มาก (CocoaPods/Maven) |
React Native New Architecture 2026
React Native ได้ปล่อย New Architecture ที่เปลี่ยนแปลงการทำงานภายในอย่างมาก ทำให้ Performance ดีขึ้นหลายเท่า ประกอบด้วย 3 ส่วนหลัก:
1. JSI (JavaScript Interface)
แทนที่ Bridge เดิมที่ส่งข้อมูลแบบ Asynchronous JSON Serialization ด้วย JSI ที่เป็น C++ Interface ให้ JavaScript เรียก Native Functions ได้โดยตรงแบบ Synchronous ข้อดีคือ:
- ไม่ต้อง Serialize/Deserialize JSON ทำให้เร็วขึ้นมาก
- JavaScript สามารถ Hold Reference ไปยัง C++ Host Objects ได้
- รองรับ JavaScript Engine หลายตัว (Hermes, V8, JSC)
- เรียก Native Functions แบบ Synchronous ได้ (ไม่ต้องรอ Bridge)
2. Fabric (New Rendering System)
Fabric เป็น Rendering System ใหม่ที่แทนที่ระบบเดิม โดยใช้ C++ เป็นหลักในการสร้าง Shadow Tree ทำให้:
- Render ได้เร็วขึ้นเพราะไม่ต้องข้าม Bridge
- รองรับ Concurrent Rendering ที่มาจาก React 18
- Prioritize การ Render ได้ (Urgent vs Non-urgent updates)
- Layout คำนวณใน C++ โดยตรง (Yoga Engine)
3. TurboModules
TurboModules แทนที่ระบบ Native Modules เดิมด้วยระบบ Lazy Loading:
- โหลด Native Module เฉพาะตอนที่ใช้งานจริง (ไม่โหลดทั้งหมดตอนเริ่ม App)
- ใช้ JSI ในการสื่อสาร ทำให้เร็วกว่า Bridge เดิม
- รองรับ Code Generation (Codegen) จาก TypeScript Types
- ลด Startup Time ของ App อย่างมีนัยสำคัญ
// ตัวอย่าง TurboModule Spec (TypeScript)
import type { TurboModule } from 'react-native';
import { TurboModuleRegistry } from 'react-native';
export interface Spec extends TurboModule {
getDeviceName(): string; // Synchronous call ผ่าน JSI
getBatteryLevel(): Promise<number>; // Async call
setVolume(level: number): void;
}
export default TurboModuleRegistry.getEnforcing<Spec>('DeviceInfo');
Expo Framework — เริ่มต้นง่ายที่สุด
Expo คือ Platform ที่ครอบ React Native อีกชั้น ทำให้การพัฒนา Mobile App ง่ายขึ้นมาก โดยจัดการเรื่อง Native Build, Configuration และ Deployment ให้ทั้งหมด ในปี 2026 Expo เป็น Recommended Way ในการเริ่มต้น React Native Project ใหม่
Managed vs Bare Workflow
| คุณสมบัติ | Managed Workflow | Bare Workflow |
|---|---|---|
| Native Code Access | ผ่าน Config Plugins เท่านั้น | เข้าถึง iOS/Android โดยตรง |
| Build | EAS Build (Cloud) | Local หรือ EAS Build |
| Configuration | app.json / app.config.js | app.json + Native config files |
| Ejection | prebuild ได้ทุกเมื่อ | ไม่ต้อง eject |
| เหมาะกับ | โปรเจกต์ใหม่ ทั่วไป | ต้องการ Custom Native Code |
EAS (Expo Application Services)
EAS เป็นชุดเครื่องมือ Cloud Services ที่ Expo จัดให้:
- EAS Build: Build iOS/Android App บน Cloud (ไม่ต้องมี Mac สำหรับ iOS Build)
- EAS Submit: ส่ง App ขึ้น App Store / Google Play โดยอัตโนมัติ
- EAS Update: OTA Updates ส่ง JavaScript Bundle ใหม่ไปยังผู้ใช้โดยไม่ต้องผ่าน Store
เริ่มต้นสร้าง React Native Project
# ติดตั้ง Node.js (18+) แล้วสร้าง Project ด้วย Expo
npx create-expo-app@latest MyApp
cd MyApp
# รัน Development Server
npx expo start
# ทดสอบบนมือถือ:
# 1. ติดตั้ง Expo Go App จาก App Store / Play Store
# 2. Scan QR Code จาก Terminal
# รันบน Simulator/Emulator
npx expo start --ios # iOS Simulator (ต้องมี Xcode)
npx expo start --android # Android Emulator (ต้องมี Android Studio)
# โครงสร้างไฟล์
# MyApp/
# ├── app/ # Expo Router pages
# │ ├── (tabs)/ # Tab navigation
# │ ├── _layout.tsx # Root layout
# │ └── index.tsx # Home screen
# ├── components/ # Reusable components
# ├── constants/ # Colors, config
# ├── assets/ # Images, fonts
# ├── app.json # Expo configuration
# ├── package.json
# └── tsconfig.json
Core Components ที่ต้องรู้
React Native ใช้ Component เฉพาะแทน HTML Elements:
import React from 'react';
import {
View, Text, ScrollView, FlatList,
Image, TouchableOpacity, TextInput,
StyleSheet, SafeAreaView, StatusBar
} from 'react-native';
export default function HomeScreen() {
return (
<SafeAreaView style={styles.container}>
<StatusBar barStyle="dark-content" />
<ScrollView contentContainerStyle={styles.scrollContent}>
{/* View = div */}
<View style={styles.header}>
{/* Text = p/span (ข้อความต้องอยู่ใน Text เสมอ) */}
<Text style={styles.title}>สวัสดี React Native</Text>
<Text style={styles.subtitle}>Mobile App Development 2026</Text>
</View>
{/* Image */}
<Image
source={{ uri: 'https://example.com/photo.jpg' }}
style={styles.image}
resizeMode="cover"
/>
{/* TextInput = input */}
<TextInput
style={styles.input}
placeholder="ค้นหา..."
onChangeText={(text) => console.log(text)}
/>
{/* TouchableOpacity = button */}
<TouchableOpacity
style={styles.button}
onPress={() => alert('กดแล้ว!')}
>
<Text style={styles.buttonText}>กดที่นี่</Text>
</TouchableOpacity>
</ScrollView>
</SafeAreaView>
);
}
const styles = StyleSheet.create({
container: { flex: 1, backgroundColor: '#fff' },
scrollContent: { padding: 20 },
header: { marginBottom: 20 },
title: { fontSize: 28, fontWeight: 'bold', color: '#1e293b' },
subtitle: { fontSize: 16, color: '#64748b', marginTop: 4 },
image: { width: '100%', height: 200, borderRadius: 12 },
input: {
borderWidth: 1, borderColor: '#e2e8f0', borderRadius: 8,
padding: 12, fontSize: 16, marginVertical: 12
},
button: {
backgroundColor: '#2563eb', padding: 14, borderRadius: 8,
alignItems: 'center'
},
buttonText: { color: '#fff', fontSize: 16, fontWeight: '600' },
});
FlatList — รายการข้อมูลขนาดใหญ่
import { FlatList, View, Text } from 'react-native';
const DATA = [
{ id: '1', title: 'รายการที่ 1' },
{ id: '2', title: 'รายการที่ 2' },
{ id: '3', title: 'รายการที่ 3' },
];
function ItemList() {
return (
<FlatList
data={DATA}
keyExtractor={(item) => item.id}
renderItem={({ item }) => (
<View style={{ padding: 16, borderBottomWidth: 1, borderBottomColor: '#eee' }}>
<Text style={{ fontSize: 16 }}>{item.title}</Text>
</View>
)}
ListEmptyComponent={<Text>ไม่มีข้อมูล</Text>}
refreshing={false}
onRefresh={() => console.log('Refresh!')}
onEndReached={() => console.log('Load more!')}
onEndReachedThreshold={0.5}
/>
);
}
FlatList แทน ScrollView เมื่อมีข้อมูลมากกว่า 20-30 รายการ เพราะ FlatList ใช้ Virtualization (Render เฉพาะ Item ที่อยู่บนหน้าจอ) ทำให้ประหยัด Memory
Navigation — จัดการหน้าจอ
Expo Router (File-based Routing)
Expo Router เป็นระบบ Navigation ที่ใช้ File System เหมือน Next.js:
// app/_layout.tsx — Root Layout
import { Stack } from 'expo-router';
export default function RootLayout() {
return (
<Stack>
<Stack.Screen name="(tabs)" options={{ headerShown: false }} />
<Stack.Screen name="details/[id]" options={{ title: 'รายละเอียด' }} />
<Stack.Screen name="modal" options={{ presentation: 'modal' }} />
</Stack>
);
}
// app/(tabs)/_layout.tsx — Tab Layout
import { Tabs } from 'expo-router';
import { Ionicons } from '@expo/vector-icons';
export default function TabLayout() {
return (
<Tabs screenOptions={{ tabBarActiveTintColor: '#2563eb' }}>
<Tabs.Screen
name="index"
options={{
title: 'หน้าหลัก',
tabBarIcon: ({ color }) => <Ionicons name="home" size={24} color={color} />
}}
/>
<Tabs.Screen
name="profile"
options={{
title: 'โปรไฟล์',
tabBarIcon: ({ color }) => <Ionicons name="person" size={24} color={color} />
}}
/>
</Tabs>
);
}
// app/details/[id].tsx — Dynamic Route
import { useLocalSearchParams } from 'expo-router';
import { View, Text } from 'react-native';
export default function DetailsScreen() {
const { id } = useLocalSearchParams();
return (
<View>
<Text>รายละเอียด ID: {id}</Text>
</View>
);
}
// การ Navigate
import { Link, router } from 'expo-router';
// แบบ Link Component
<Link href="/details/123">ดูรายละเอียด</Link>
// แบบ Programmatic
router.push('/details/123');
router.replace('/login');
router.back();
React Navigation (Classic)
# ติดตั้ง
npm 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();
function App() {
return (
<NavigationContainer>
<Stack.Navigator>
<Stack.Screen name="Home" component={HomeScreen} />
<Stack.Screen name="Details" component={DetailsScreen} />
</Stack.Navigator>
</NavigationContainer>
);
}
State Management
useState + Context (โปรเจกต์เล็ก)
import React, { createContext, useContext, useState } from 'react';
// สร้าง Context
const AuthContext = createContext(null);
export function AuthProvider({ children }) {
const [user, setUser] = useState(null);
const login = async (email, password) => {
const response = await fetch('/api/login', {
method: 'POST',
body: JSON.stringify({ email, password })
});
const data = await response.json();
setUser(data.user);
};
const logout = () => setUser(null);
return (
<AuthContext.Provider value={{ user, login, logout }}>
{children}
</AuthContext.Provider>
);
}
// ใช้งานใน Component
function ProfileScreen() {
const { user, logout } = useContext(AuthContext);
return (
<View>
<Text>ยินดีต้อนรับ {user?.name}</Text>
<Button title="ออกจากระบบ" onPress={logout} />
</View>
);
}
Zustand (โปรเจกต์กลาง — แนะนำ)
// npm install zustand
import { create } from 'zustand';
interface CartStore {
items: CartItem[];
addItem: (item: CartItem) => void;
removeItem: (id: string) => void;
clearCart: () => void;
total: () => number;
}
const useCartStore = create<CartStore>((set, get) => ({
items: [],
addItem: (item) => set((state) => ({
items: [...state.items, item]
})),
removeItem: (id) => set((state) => ({
items: state.items.filter(i => i.id !== id)
})),
clearCart: () => set({ items: [] }),
total: () => get().items.reduce((sum, i) => sum + i.price, 0),
}));
// ใช้ใน Component — ง่ายมาก ไม่ต้อง Provider
function CartScreen() {
const items = useCartStore((s) => s.items);
const clearCart = useCartStore((s) => s.clearCart);
return (
<FlatList
data={items}
renderItem={({ item }) => <CartItem item={item} />}
/>
);
}
Redux Toolkit (โปรเจกต์ใหญ่)
// npm install @reduxjs/toolkit react-redux
import { configureStore, createSlice } from '@reduxjs/toolkit';
const userSlice = createSlice({
name: 'user',
initialState: { profile: null, loading: false },
reducers: {
setUser: (state, action) => { state.profile = action.payload; },
clearUser: (state) => { state.profile = null; },
},
});
const store = configureStore({
reducer: { user: userSlice.reducer },
});
Styling — การจัดรูปแบบ
StyleSheet (มาตรฐาน)
React Native ใช้ Flexbox เป็นหลักในการจัด Layout คล้าย CSS แต่ค่า Default ต่างกัน:
flexDirectiondefault เป็น'column'(ไม่ใช่ 'row' เหมือน Web)- ทุก View มี
display: 'flex'เป็น Default - ใช้ตัวเลข (ไม่มีหน่วย) เช่น
padding: 16ไม่ใช่'16px' - ไม่มี CSS Inheritance (ยกเว้นใน Text Component)
NativeWind (Tailwind CSS สำหรับ React Native)
# ติดตั้ง NativeWind v4
npm install nativewind tailwindcss
// ใช้ className เหมือน Tailwind CSS
import { View, Text, Pressable } from 'react-native';
export default function Card() {
return (
<View className="bg-white rounded-xl p-4 shadow-md mx-4 my-2">
<Text className="text-lg font-bold text-gray-800">
NativeWind Card
</Text>
<Text className="text-sm text-gray-500 mt-1">
ใช้ Tailwind CSS ใน React Native ได้เลย
</Text>
<Pressable className="bg-blue-500 rounded-lg py-2 mt-3 active:bg-blue-600">
<Text className="text-white text-center font-semibold">
กดที่นี่
</Text>
</Pressable>
</View>
);
}
Native Modules — เข้าถึงฟีเจอร์ของเครื่อง
Camera (กล้อง)
// npx expo install expo-camera
import { CameraView, useCameraPermissions } from 'expo-camera';
import { useState } from 'react';
import { View, Text, TouchableOpacity } from 'react-native';
export default function CameraScreen() {
const [facing, setFacing] = useState('back');
const [permission, requestPermission] = useCameraPermissions();
if (!permission) return <View />;
if (!permission.granted) {
return (
<View style={{ flex: 1, justifyContent: 'center', alignItems: 'center' }}>
<Text>ต้องการสิทธิ์เข้าถึงกล้อง</Text>
<TouchableOpacity onPress={requestPermission}>
<Text>อนุญาต</Text>
</TouchableOpacity>
</View>
);
}
return (
<CameraView style={{ flex: 1 }} facing={facing}>
<TouchableOpacity onPress={() => setFacing(f => f === 'back' ? 'front' : 'back')}>
<Text style={{ color: '#fff', fontSize: 18 }}>สลับกล้อง</Text>
</TouchableOpacity>
</CameraView>
);
}
Location (ตำแหน่ง GPS)
// npx expo install expo-location
import * as Location from 'expo-location';
async function getLocation() {
const { status } = await Location.requestForegroundPermissionsAsync();
if (status !== 'granted') {
alert('ไม่ได้รับสิทธิ์เข้าถึงตำแหน่ง');
return;
}
const location = await Location.getCurrentPositionAsync({});
console.log(location.coords.latitude, location.coords.longitude);
// Reverse Geocoding
const [address] = await Location.reverseGeocodeAsync({
latitude: location.coords.latitude,
longitude: location.coords.longitude,
});
console.log(address.city, address.country);
}
API Integration — เชื่อมต่อ Backend
// ใช้ fetch (built-in) หรือ axios
// npm install axios @tanstack/react-query
import { useQuery, useMutation } from '@tanstack/react-query';
import axios from 'axios';
const API_URL = 'https://api.example.com';
// GET — ดึงข้อมูล
function useProducts() {
return useQuery({
queryKey: ['products'],
queryFn: async () => {
const { data } = await axios.get(`${API_URL}/products`);
return data;
},
staleTime: 5 * 60 * 1000, // Cache 5 นาที
});
}
// POST — ส่งข้อมูล
function useCreateOrder() {
return useMutation({
mutationFn: async (order) => {
const { data } = await axios.post(`${API_URL}/orders`, order);
return data;
},
onSuccess: () => {
// Invalidate cache เพื่อ Refetch
queryClient.invalidateQueries({ queryKey: ['orders'] });
},
});
}
// ใช้ใน Component
function ProductList() {
const { data: products, isLoading, error } = useProducts();
if (isLoading) return <ActivityIndicator />;
if (error) return <Text>เกิดข้อผิดพลาด</Text>;
return (
<FlatList
data={products}
renderItem={({ item }) => (
<Text>{item.name} - ฿{item.price}</Text>
)}
/>
);
}
Authentication — ระบบล็อกอิน
// เก็บ Token ด้วย expo-secure-store
// npx expo install expo-secure-store
import * as SecureStore from 'expo-secure-store';
async function saveToken(token: string) {
await SecureStore.setItemAsync('userToken', token);
}
async function getToken() {
return await SecureStore.getItemAsync('userToken');
}
async function deleteToken() {
await SecureStore.deleteItemAsync('userToken');
}
// Auth Flow ทั่วไป
function useAuth() {
const [isAuthenticated, setIsAuthenticated] = useState(false);
const [isLoading, setIsLoading] = useState(true);
useEffect(() => {
checkAuth();
}, []);
const checkAuth = async () => {
const token = await getToken();
if (token) {
// ตรวจสอบ token กับ server
try {
await axios.get('/api/me', {
headers: { Authorization: `Bearer ${token}` }
});
setIsAuthenticated(true);
} catch {
await deleteToken();
}
}
setIsLoading(false);
};
const login = async (email: string, password: string) => {
const { data } = await axios.post('/api/login', { email, password });
await saveToken(data.token);
setIsAuthenticated(true);
};
const logout = async () => {
await deleteToken();
setIsAuthenticated(false);
};
return { isAuthenticated, isLoading, login, logout };
}
Push Notifications
// npx expo install expo-notifications expo-device expo-constants
import * as Notifications from 'expo-notifications';
import * as Device from 'expo-device';
import Constants from 'expo-constants';
// ตั้งค่าการแสดง Notification
Notifications.setNotificationHandler({
handleNotification: async () => ({
shouldShowAlert: true,
shouldPlaySound: true,
shouldSetBadge: true,
}),
});
// ขอ Permission และรับ Push Token
async function registerForPushNotifications() {
if (!Device.isDevice) {
alert('Push Notifications ใช้ได้บนเครื่องจริงเท่านั้น');
return;
}
const { status: existingStatus } = await Notifications.getPermissionsAsync();
let finalStatus = existingStatus;
if (existingStatus !== 'granted') {
const { status } = await Notifications.requestPermissionsAsync();
finalStatus = status;
}
if (finalStatus !== 'granted') {
alert('ไม่ได้รับสิทธิ์ Push Notification');
return;
}
// รับ Expo Push Token
const token = await Notifications.getExpoPushTokenAsync({
projectId: Constants.expoConfig?.extra?.eas?.projectId,
});
console.log('Push Token:', token.data);
// ส่ง Token ไปเก็บที่ Server
await fetch('https://api.example.com/push-tokens', {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({ token: token.data }),
});
return token;
}
// รับ Notification ใน App
useEffect(() => {
// เมื่อได้รับ Notification ขณะ App เปิดอยู่
const subscription = Notifications.addNotificationReceivedListener(notification => {
console.log('Received:', notification);
});
// เมื่อผู้ใช้กด Notification
const responseSubscription = Notifications.addNotificationResponseReceivedListener(response => {
const data = response.notification.request.content.data;
// Navigate ไปหน้าที่เกี่ยวข้อง
router.push(`/details/${data.itemId}`);
});
return () => {
subscription.remove();
responseSubscription.remove();
};
}, []);
Testing — ทดสอบแอป
Jest — Unit Testing
// __tests__/utils.test.ts
import { formatPrice, validateEmail } from '../utils';
describe('formatPrice', () => {
it('should format number with commas', () => {
expect(formatPrice(1000)).toBe('1,000');
expect(formatPrice(1234567)).toBe('1,234,567');
});
it('should handle zero', () => {
expect(formatPrice(0)).toBe('0');
});
});
describe('validateEmail', () => {
it('should return true for valid email', () => {
expect(validateEmail('test@example.com')).toBe(true);
});
it('should return false for invalid email', () => {
expect(validateEmail('invalid')).toBe(false);
});
});
React Native Testing Library — Component Testing
// npm install @testing-library/react-native
import { render, fireEvent, screen } from '@testing-library/react-native';
import LoginScreen from '../screens/LoginScreen';
describe('LoginScreen', () => {
it('should show error for empty fields', () => {
render(<LoginScreen />);
fireEvent.press(screen.getByText('เข้าสู่ระบบ'));
expect(screen.getByText('กรุณากรอก Email')).toBeTruthy();
});
it('should call login on valid input', () => {
const mockLogin = jest.fn();
render(<LoginScreen onLogin={mockLogin} />);
fireEvent.changeText(screen.getByPlaceholderText('Email'), 'test@test.com');
fireEvent.changeText(screen.getByPlaceholderText('Password'), '123456');
fireEvent.press(screen.getByText('เข้าสู่ระบบ'));
expect(mockLogin).toHaveBeenCalledWith('test@test.com', '123456');
});
});
Debugging — แก้ไขปัญหา
เครื่องมือ Debug สำหรับ React Native:
- React DevTools: ดู Component Tree, Props, State
- Flipper: Network Inspector, Layout Inspector, Database Viewer
- Console.log: แสดงใน Terminal ที่รัน
npx expo start - React Native Debugger: Redux DevTools + Network + Console
- Expo DevTools: กด
jใน Terminal เพื่อเปิด JS Debugger
// Performance Monitoring
import { useEffect } from 'react';
import { InteractionManager } from 'react-native';
function HeavyScreen() {
useEffect(() => {
// รอให้ Animation เสร็จก่อนทำงานหนัก
const task = InteractionManager.runAfterInteractions(() => {
// Load data, compute, etc.
loadHeavyData();
});
return () => task.cancel();
}, []);
}
App Store Submission — ส่งแอปขึ้น Store
# 1. ตั้งค่า EAS Build
npx eas-cli login
npx eas build:configure
# 2. Build สำหรับ Production
npx eas build --platform ios --profile production
npx eas build --platform android --profile production
# 3. Submit ไปยัง Store
npx eas submit --platform ios # App Store Connect
npx eas submit --platform android # Google Play Console
# eas.json Configuration
{
"build": {
"development": {
"developmentClient": true,
"distribution": "internal",
"ios": { "simulator": true }
},
"preview": {
"distribution": "internal",
"android": { "buildType": "apk" }
},
"production": {
"autoIncrement": true,
"ios": {
"bundleIdentifier": "com.yourcompany.yourapp"
},
"android": {
"package": "com.yourcompany.yourapp"
}
}
},
"submit": {
"production": {
"ios": {
"appleId": "your@apple.id",
"ascAppId": "1234567890",
"appleTeamId": "TEAM_ID"
},
"android": {
"serviceAccountKeyPath": "./google-service-account.json",
"track": "production"
}
}
}
}
OTA Updates — อัปเดตแอปโดยไม่ผ่าน Store
# EAS Update ส่ง JavaScript Bundle ใหม่ให้ผู้ใช้ทันที
# ไม่ต้องรอ Review จาก Apple/Google
# ตั้งค่า
npx eas update:configure
# ส่งอัปเดต
npx eas update --branch production --message "แก้ไขบั๊กหน้า Login"
# อัปเดตเฉพาะ Platform
npx eas update --branch production --platform ios
// ตรวจสอบ Update ใน App
import * as Updates from 'expo-updates';
async function checkForUpdates() {
try {
const update = await Updates.checkForUpdateAsync();
if (update.isAvailable) {
await Updates.fetchUpdateAsync();
// แจ้งผู้ใช้แล้ว Reload
Alert.alert(
'อัปเดตใหม่',
'มีเวอร์ชันใหม่ ต้องการรีสตาร์ทแอปหรือไม่?',
[
{ text: 'ทีหลัง' },
{ text: 'รีสตาร์ท', onPress: () => Updates.reloadAsync() },
]
);
}
} catch (e) {
console.error('Update check failed:', e);
}
}
Performance Optimization
เทคนิคเพิ่มประสิทธิภาพ React Native App:
1. Memoization
import { memo, useMemo, useCallback } from 'react';
// memo — ป้องกัน Re-render ที่ไม่จำเป็น
const ProductCard = memo(function ProductCard({ product, onPress }) {
return (
<TouchableOpacity onPress={() => onPress(product.id)}>
<Text>{product.name}</Text>
</TouchableOpacity>
);
});
// useMemo — Cache ค่าที่คำนวณแพง
const sortedProducts = useMemo(() =>
products.sort((a, b) => b.rating - a.rating),
[products]
);
// useCallback — Cache Function Reference
const handlePress = useCallback((id) => {
navigation.navigate('Details', { id });
}, [navigation]);
2. Image Optimization
// ใช้ expo-image แทน Image Component
// npx expo install expo-image
import { Image } from 'expo-image';
<Image
source={{ uri: 'https://example.com/photo.jpg' }}
style={{ width: 200, height: 200 }}
contentFit="cover"
placeholder={blurhash} // แสดง Blurhash ขณะโหลด
transition={300} // Fade-in Animation
cachePolicy="memory-disk" // Cache ทั้ง Memory และ Disk
/>
3. Hermes Engine
Hermes เป็น JavaScript Engine ที่ Meta สร้างมาเฉพาะสำหรับ React Native:
- Startup Time เร็วขึ้น 2-3 เท่า (Bytecode Precompilation)
- ใช้ Memory น้อยลง 30-50%
- Garbage Collection ดีขึ้น
- เป็น Default Engine ใน React Native 0.70+ และ Expo SDK 50+
Popular Libraries ที่ใช้บ่อย
| Library | หน้าที่ | ติดตั้ง |
|---|---|---|
| React Native Paper | Material Design UI Kit | npm install react-native-paper |
| NativeBase | Cross-Platform UI Components | npm install native-base |
| React Native Reanimated | Smooth Animations (60fps) | npx expo install react-native-reanimated |
| React Native Gesture Handler | Native Gestures (Swipe, Pan) | npx expo install react-native-gesture-handler |
| expo-image | Fast Image Loading + Cache | npx expo install expo-image |
| React Native MMKV | Fast Key-Value Storage | npm install react-native-mmkv |
| React Native SVG | SVG Rendering | npx expo install react-native-svg |
| Lottie React Native | JSON Animations | npm install lottie-react-native |
| React Native Maps | Google Maps / Apple Maps | npx expo install react-native-maps |
| @tanstack/react-query | Data Fetching + Caching | npm install @tanstack/react-query |
โครงสร้างโปรเจกต์ที่แนะนำ
my-app/
├── app/ # Expo Router Pages
│ ├── (auth)/ # Auth Group
│ │ ├── login.tsx
│ │ └── register.tsx
│ ├── (tabs)/ # Main Tab Group
│ │ ├── index.tsx # Home
│ │ ├── search.tsx # Search
│ │ ├── cart.tsx # Cart
│ │ └── profile.tsx # Profile
│ ├── product/[id].tsx # Product Details
│ ├── _layout.tsx # Root Layout
│ └── +not-found.tsx # 404 Page
├── components/ # Reusable UI Components
│ ├── ui/ # Base Components
│ │ ├── Button.tsx
│ │ ├── Input.tsx
│ │ └── Card.tsx
│ └── product/ # Feature Components
│ ├── ProductCard.tsx
│ └── ProductList.tsx
├── hooks/ # Custom Hooks
│ ├── useAuth.ts
│ └── useProducts.ts
├── services/ # API Services
│ ├── api.ts # Axios Instance
│ ├── auth.ts # Auth API
│ └── products.ts # Products API
├── stores/ # Zustand Stores
│ ├── authStore.ts
│ └── cartStore.ts
├── utils/ # Helper Functions
│ ├── format.ts
│ └── validation.ts
├── constants/ # App Constants
│ ├── Colors.ts
│ └── Config.ts
├── assets/ # Static Assets
│ ├── images/
│ └── fonts/
├── app.json # Expo Config
├── eas.json # EAS Build Config
├── tailwind.config.js # NativeWind Config
└── tsconfig.json
สรุป
React Native ในปี 2026 เป็น Framework ที่สมบูรณ์แบบสำหรับการพัฒนา Mobile App ด้วย New Architecture (JSI, Fabric, TurboModules) ที่ทำให้ Performance เทียบเท่า Native App และ Expo ที่ช่วยให้การ Build, Deploy และ Update ง่ายขึ้นหลายเท่า ทำให้นักพัฒนาสามารถสร้างแอปคุณภาพสูงจาก Codebase เดียวสำหรับทั้ง iOS และ Android
จุดเริ่มต้นที่ดีคือ: ติดตั้ง Node.js รัน npx create-expo-app แล้วเริ่มทดลองสร้างแอปแรกของคุณ React Native มี Community ขนาดใหญ่ Documentation ดีเยี่ยม และ Libraries มากมายที่ช่วยให้คุณสร้างแอปได้รวดเร็ว ไม่ว่าจะเป็นแอป E-commerce, Social Media, หรือ Enterprise App ก็สามารถทำได้ด้วย React Native
สิ่งสำคัญที่สุดคือเริ่มลงมือทำ สร้างโปรเจกต์เล็กๆ ก่อน เรียนรู้จากการปฏิบัติจริง แล้วค่อยๆ เพิ่มความซับซ้อน เมื่อคุณเข้าใจพื้นฐานดีแล้ว คุณจะสามารถสร้าง Mobile App ที่ซับซ้อนได้อย่างมั่นใจ
