Home > Blog > tech

React Native คืออะไร? สอนสร้าง Mobile App ด้วย React Native และ Expo 2026

react native mobile development guide
React Native Mobile Development Guide 2026
2026-04-08 | tech | 3500 words

การพัฒนา 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 คือ:

แอปที่สร้างด้วย React Native จะมี Look and Feel เหมือน Native App เพราะใช้ UI Component จริงของแต่ละ Platform ไม่ได้ใช้ HTML/CSS ใน WebView เหมือนพวก Cordova หรือ Ionic รุ่นเก่า

React Native vs Flutter vs Native: เปรียบเทียบ 2026

คุณสมบัติReact NativeFlutterNative (Swift/Kotlin)
ภาษาJavaScript / TypeScriptDartSwift (iOS) / Kotlin (Android)
RenderingNative ComponentsSkia Engine (Custom Rendering)Native Components
ประสิทธิภาพใกล้เคียง Native (JSI)ใกล้เคียง Nativeดีที่สุด
Hot ReloadFast RefreshHot ReloadSwift Previews / Compose Preview
Code SharingiOS + Android + WebiOS + 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/JavaScript อยู่แล้ว เลือก React Native ถ้าต้องการ UI ที่ Pixel-perfect เหมือนกันทุก Platform เลือก Flutter ถ้าต้องการ Performance สูงสุดและมีทีมแยก iOS/Android เลือก Native

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 ข้อดีคือ:

2. Fabric (New Rendering System)

Fabric เป็น Rendering System ใหม่ที่แทนที่ระบบเดิม โดยใช้ C++ เป็นหลักในการสร้าง Shadow Tree ทำให้:

3. TurboModules

TurboModules แทนที่ระบบ Native Modules เดิมด้วยระบบ Lazy Loading:

// ตัวอย่าง 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 WorkflowBare Workflow
Native Code Accessผ่าน Config Plugins เท่านั้นเข้าถึง iOS/Android โดยตรง
BuildEAS Build (Cloud)Local หรือ EAS Build
Configurationapp.json / app.config.jsapp.json + Native config files
Ejectionprebuild ได้ทุกเมื่อไม่ต้อง eject
เหมาะกับโปรเจกต์ใหม่ ทั่วไปต้องการ Custom Native Code

EAS (Expo Application Services)

EAS เป็นชุดเครื่องมือ Cloud Services ที่ Expo จัดให้:

เริ่มต้นสร้าง 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 ต่างกัน:

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:

// 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:

Popular Libraries ที่ใช้บ่อย

Libraryหน้าที่ติดตั้ง
React Native PaperMaterial Design UI Kitnpm install react-native-paper
NativeBaseCross-Platform UI Componentsnpm install native-base
React Native ReanimatedSmooth Animations (60fps)npx expo install react-native-reanimated
React Native Gesture HandlerNative Gestures (Swipe, Pan)npx expo install react-native-gesture-handler
expo-imageFast Image Loading + Cachenpx expo install expo-image
React Native MMKVFast Key-Value Storagenpm install react-native-mmkv
React Native SVGSVG Renderingnpx expo install react-native-svg
Lottie React NativeJSON Animationsnpm install lottie-react-native
React Native MapsGoogle Maps / Apple Mapsnpx expo install react-native-maps
@tanstack/react-queryData Fetching + Cachingnpm 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 ที่ซับซ้อนได้อย่างมั่นใจ


Back to Blog | iCafe Forex | SiamLanCard | Siam2R