เป้าหมาย
จบสัปดาห์นี้ คุณจะ:
- อธิบายความต่างระหว่าง React Native กับ Expo ได้
- สร้างโปรเจกต์ด้วย create-expo-app และรันบนมือถือจริงด้วย Expo Go
- อ่านโครงสร้างโปรเจกต์และเข้าใจ Expo Router (routing ตามไฟล์)
- บอกได้ว่างานแบบไหนที่ Expo ไม่เหมาะ
Expo คืออะไร
React Native คือ framework ที่เขียน UI ด้วย React (JavaScript/TypeScript) แล้วแสดงผลเป็น component แบบ native จริงทั้ง iOS และ Android
Expo คือชุดเครื่องมือที่ครอบ React Native ให้เริ่มงานและส่งแอปขึ้น store ได้ง่ายขึ้น และเป็นทางที่เอกสาร React Native แนะนำสำหรับโปรเจกต์ใหม่
| ส่วนประกอบ | ทำหน้าที่ |
|---|---|
| Expo CLI | สร้าง รัน และจัดการโปรเจกต์ (npx expo …) |
| Expo Go | แอปบนมือถือ สแกน QR แล้วรันโค้ดทันที ไม่ต้อง build |
| Expo SDK | ไลบรารีพร้อมใช้ เช่น กล้อง ตำแหน่ง การแจ้งเตือน ไฟล์ |
| Expo Router | ระบบนำทางแบบ file-based คล้าย Next.js |
| EAS | Build บนคลาวด์ ส่งขึ้น store และอัปเดตแบบ OTA |
ติดตั้งและรันแอปแรก
- ติดตั้ง Node.js (LTS), VS Code และแอป Expo Go บนมือถือ
- สร้างโปรเจกต์และเปิด dev server ด้วยคำสั่งด้านล่าง
- สแกน QR ด้วย Expo Go (Android) หรือแอปกล้อง (iOS) โดยมือถือกับคอมอยู่ Wi‑Fi เดียวกัน
- แก้ข้อความใน
app/(tabs)/index.tsxแล้วดู Fast Refresh บนมือถือ
npx create-expo-app@latest my-appcd my-appnpx expo startสแกนแล้วต่อไม่ติด?มักเป็นเพราะมือถือกับคอมอยู่คนละเครือข่าย ให้ใช้
npx expo start --tunnel| ไฟล์/โฟลเดอร์ | ใช้ทำอะไร |
|---|---|
| app/ | หน้าจอทั้งหมด ชื่อไฟล์ = เส้นทาง (route) |
| app/_layout.tsx | layout และ navigator ครอบทุกหน้า |
| components/ | component ที่ใช้ซ้ำ |
| assets/ | รูป ไอคอน ฟอนต์ |
| app.json | ชื่อแอป ไอคอน bundle id สิทธิ์การเข้าถึง |
| package.json | ไลบรารีที่ติดตั้ง (ใช้ npx expo install ให้เวอร์ชันตรงกับ SDK) |
เขียนหน้าแรก
แทนที่เนื้อหาในไฟล์หน้าแรกด้วยโค้ดนี้ แล้ว save ดูผลบนมือถือ
app/(tabs)/index.tsx
1import { useState } from 'react';2import { Pressable, StyleSheet, Text, View } from 'react-native';3import { Link } from 'expo-router';45export default function HomeScreen() {6 const [count, setCount] = useState(0);78 return (9 <View style={styles.container}>10 <Text style={styles.title}>Hello, Expo!</Text>1112 <Pressable style={styles.button} onPress={() => setCount(count + 1)}>13 <Text style={styles.buttonText}>กดแล้ว {count} ครั้ง</Text>14 </Pressable>1516 <Link href="/about" style={styles.link}>ไปหน้า About →</Link>17 </View>18 );19}2021const styles = StyleSheet.create({22 container: { flex: 1, alignItems: 'center', justifyContent: 'center', gap: 16, backgroundColor: '#09090b' },23 title: { fontSize: 32, fontWeight: '700', color: '#fafafa' },24 button: { backgroundColor: '#fafafa', paddingHorizontal: 20, paddingVertical: 12, borderRadius: 8 },25 buttonText: { color: '#09090b', fontWeight: '600' },26 link: { color: '#a1a1aa' },27});
- useState เก็บค่าที่เปลี่ยนได้ ทุกครั้งที่ setCount ถูกเรียก หน้าจอจะวาดใหม่
- View คือกล่อง (เหมือน div) และ Text คือข้อความ ข้อความต้องอยู่ใน Text เสมอ
- Pressable ทำให้กดได้ และ onPress คือสิ่งที่เกิดเมื่อนิ้วแตะ
- Link จาก Expo Router พาไปหน้าอื่น
- StyleSheet เขียน style คล้าย CSS แต่เป็น camelCase และไม่มีหน่วย px
เพิ่มหน้าใหม่ด้วย Expo Router
สร้างไฟล์ app/about.tsx แล้ว Expo Router จะสร้างหน้า /about ให้อัตโนมัติ ไม่ต้องลงทะเบียนเส้นทางเอง
app/about.tsx
1import { Text, View } from 'react-native';2import { Link } from 'expo-router';34// ไฟล์ app/about.tsx = หน้า /about อัตโนมัติ5export default function AboutScreen() {6 return (7 <View style={{ flex: 1, alignItems: 'center', justifyContent: 'center', gap: 12 }}>8 <Text style={{ fontSize: 24 }}>About</Text>9 <Link href="/">กลับหน้าแรก</Link>10 </View>11 );12}
Expo vs Flutter vs Native
คอร์สนี้เลือก Expo เพราะต่อยอดความรู้ React จากเว็บได้ เขียนโค้ดชุดเดียวได้ทั้ง iOS และ Android และ build iOS ได้แม้ไม่มี Mac
| เกณฑ์ | Expo (React Native) | Flutter | Native (Kotlin/Swift) |
|---|---|---|---|
| ภาษา | JavaScript/TypeScript + React | Dart | Kotlin + Swift |
| Codebase | 1 ชุด (iOS, Android, เว็บ) | 1 ชุด (+ เว็บ, desktop) | 2 ชุดแยกกัน |
| การแสดง UI | component native ของ OS | วาดเองด้วย engine | native 100% |
| ความยากสำหรับคนรู้เว็บ | ต่ำ | กลาง (เรียน Dart) | สูง (2 ภาษา 2 toolchain) |
| Build iOS ไม่มี Mac | ได้ ผ่าน EAS Build | ต้องมี Mac หรือ CI | ต้องมี Mac + Xcode |
| อัปเดต OTA | มี (EAS Update) | ไม่มีในตัว | ไม่มี |
| Performance | ดีพอสำหรับแอปธุรกิจส่วนใหญ่ | ดี animation ลื่น | ดีที่สุด |
| ฟีเจอร์ใหม่ของ OS | รอไลบรารี หรือเขียน Expo Module | รอ plugin | ใช้ได้ทันที |
- เลือก Flutter เมื่อทีมถนัด Dart หรือต้องการ UI ออกแบบเองที่เหมือนกันทุกแพลตฟอร์ม รวมถึง desktop
- เลือก Native เมื่อต้องการ performance สูงสุด หรือใช้ฟีเจอร์เฉพาะ OS เช่น widget, Apple Watch, CarPlay
ข้อจำกัดของ Expo
- Expo Go รันได้แค่ไลบรารีใน SDK ถ้าใช้ native library อื่นต้องทำ development build
- OTA แก้ได้แค่ JavaScript และ asset ถ้าเปลี่ยน native code หรือสิทธิ์ ต้อง build ใหม่และส่ง store
- งานกราฟิกหนัก เช่น เกม 3D, AR, วิดีโอ real-time ควรใช้ Native หรือ game engine
- ฟีเจอร์ OS ใหม่ ต้องรอไลบรารี หรือเขียน Expo Module ด้วย Swift/Kotlin เอง
- EAS Build แผนฟรีมีโควตาและคิว ใช้มากต้องจ่าย หรือ build เอง (iOS ต้องใช้ Mac)
- ต้องอัปเกรด SDK เป็นระยะ และบั๊กฝั่ง native ต้องเปิด Xcode/Android Studio ดูเอง
Development buildใช้เมื่อต้องการ native library ที่ไม่อยู่ใน Expo SDK คำสั่งด้านล่างสร้างแอปทดสอบสำหรับ Android
npx expo install expo-dev-clientnpm install -g eas-clieas logineas build:configureeas build --profile development --platform androidการบ้าน
- สร้างแอปและรันบนมือถือตัวเองด้วย Expo Go
- เปลี่ยนข้อความและสีบนหน้าแรก
- เพิ่มหน้า
app/about.tsxและapp/settings.tsxแล้วลิงก์ไปมาด้วย<Link> - เขียน 3 บรรทัด: แอปที่อยากทำเหมาะหรือไม่เหมาะกับ Expo เพราะอะไร
อ่านเพิ่ม: docs.expo.dev · reactnative.dev