React 19 เป็นการอัพเดตครั้งใหญ่ที่สุดของ React ในรอบหลายปี มาพร้อม Features ใหม่ที่เปลี่ยนวิธีเขียน React แบบพลิกโฉม ตั้งแต่ React Compiler ที่ทำ Memoization อัตโนมัติ, Server Components ที่เสถียรแล้ว, Actions สำหรับจัดการ Form และ Mutation ไปจนถึง Document Metadata ที่จัดการ title/meta ได้ใน Component โดยตรง
React Compiler — ไม่ต้อง useMemo / useCallback อีกต่อไป
// ก่อน React 19 (ต้อง Manual Memoization):
function ProductList({ products, onSelect }) {
const sortedProducts = useMemo(() => {
return products.sort((a, b) => a.price - b.price);
}, [products]);
const handleClick = useCallback((id) => {
onSelect(id);
}, [onSelect]);
return sortedProducts.map(p => (
<Product key={p.id} product={p} onClick={handleClick} />
));
}
// React 19 (React Compiler ทำให้อัตโนมัติ!):
function ProductList({ products, onSelect }) {
const sortedProducts = products.sort((a, b) => a.price - b.price);
const handleClick = (id) => {
onSelect(id);
};
return sortedProducts.map(p => (
<Product key={p.id} product={p} onClick={handleClick} />
));
}
// React Compiler จะ Memoize ให้อัตโนมัติ!
// ไม่ต้องคิดว่าอะไรต้อง useMemo อะไรต้อง useCallback
Server Components — Stable ใน React 19
// Server Component (ทำงานบน Server เท่านั้น):
// ไม่ส่ง JavaScript ไป Client = เร็วขึ้น!
// app/products/page.tsx (Server Component by default)
async function ProductsPage() {
// ดึงข้อมูลจาก Database โดยตรง (ไม่ต้อง API!)
const products = await db.product.findMany({
orderBy: { createdAt: 'desc' }
});
return (
<div>
<h1>Products</h1>
<ProductList products={products} />
<AddToCartButton /> {/* Client Component */}
</div>
);
}
// Client Component (ต้องมี 'use client'):
'use client';
function AddToCartButton() {
const [count, setCount] = useState(0);
return <button onClick={() => setCount(c => c + 1)}>Add ({count})</button>;
}
Actions — จัดการ Form และ Mutations
// React 19 Actions: จัดการ Form ง่ายขึ้นมาก
// ไม่ต้อง useState + onSubmit + loading state + error handling เอง!
// Server Action:
async function createUser(formData) {
'use server';
const name = formData.get('name');
const email = formData.get('email');
await db.user.create({ data: { name, email } });
}
// Component ใช้ Action:
function SignupForm() {
return (
<form action={createUser}>
<input name="name" placeholder="Name" />
<input name="email" type="email" placeholder="Email" />
<SubmitButton />
</form>
);
}
// useActionState Hook:
function SubmitButton() {
const { pending } = useFormStatus();
return (
<button type="submit" disabled={pending}>
{pending ? 'Saving...' : 'Sign Up'}
</button>
);
}
use() Hook — อ่าน Promise และ Context ใน Conditional
// use() Hook ใหม่ — อ่าน Promise ได้โดยตรง!
// ก่อน React 19:
function Comments({ commentsPromise }) {
const [comments, setComments] = useState(null);
useEffect(() => {
commentsPromise.then(setComments);
}, [commentsPromise]);
if (!comments) return <Loading />;
return comments.map(c => <Comment key={c.id} {...c} />);
}
// React 19 — use() Hook:
function Comments({ commentsPromise }) {
const comments = use(commentsPromise);
return comments.map(c => <Comment key={c.id} {...c} />);
}
// use() กับ Context (ใน Conditional ได้!):
function Theme({ children }) {
if (condition) {
const theme = use(ThemeContext); // ใน if ได้!
return <div className={theme}>{children}</div>;
}
return children;
}
Document Metadata — จัดการ title, meta ใน Component
// React 19: ใส่ title, meta ใน Component ได้เลย!
// ไม่ต้องใช้ react-helmet หรือ next/head อีก
function BlogPost({ post }) {
return (
<article>
<title>{post.title} | My Blog</title>
<meta name="description" content={post.excerpt} />
<meta property="og:title" content={post.title} />
<link rel="canonical" href={post.url} />
<h1>{post.title}</h1>
<p>{post.content}</p>
</article>
);
}
// React จะ Hoist ไปที่ <head> ให้อัตโนมัติ!
Asset Loading — Preload Resources
// React 19: Preload ทรัพยากรได้จาก Component
import { prefetchDNS, preconnect, preload, preinit } from 'react-dom';
function Header() {
// DNS Prefetch:
prefetchDNS('https://api.example.com');
// Preconnect:
preconnect('https://cdn.example.com');
// Preload Font:
preload('/fonts/custom.woff2', { as: 'font', type: 'font/woff2' });
// Preinit Script:
preinit('/scripts/analytics.js', { as: 'script' });
return <header>...</header>;
}
ref as Prop — ไม่ต้อง forwardRef อีกต่อไป
// ก่อน React 19 — ต้องใช้ forwardRef:
const Input = forwardRef((props, ref) => {
return <input ref={ref} {...props} />;
});
// React 19 — ref เป็น Prop ธรรมดา:
function Input({ ref, ...props }) {
return <input ref={ref} {...props} />;
}
// forwardRef ไม่จำเป็นอีกต่อไป!
Improved Error Handling
// React 19: Error Messages ดีขึ้นมาก
// Hydration Mismatch แสดง Diff ชัดเจน:
//
// Warning: Text content did not match.
// Server: "Hello World"
// Client: "Hello Thailand"
//
// Previous React: แค่บอกว่า "text content mismatch"
// React 19: บอกว่าอะไรต่างจากอะไร!
Migration Guide — อัพเกรดจาก React 18
# อัพเกรดจาก React 18 → 19:
# 1. Update Dependencies:
npm install react@19 react-dom@19
# 2. Update TypeScript Types:
npm install @types/react@19 @types/react-dom@19
# 3. Run Codemods:
npx @react-codemod/v19 .
# 4. Breaking Changes สำคัญ:
# → forwardRef ไม่จำเป็น (แต่ยังใช้ได้)
# → defaultProps ถูก Remove (ใช้ Default Parameters แทน)
# → string refs ถูก Remove (ใช้ callback ref)
# → React.createFactory ถูก Remove
# → Legacy Context ถูก Remove
สรุป
React 19 เป็นก้าวกระโดดครั้งใหญ่ที่ทำให้การเขียน React ง่ายขึ้น เร็วขึ้น และทรงพลังมากขึ้น React Compiler ช่วยลดภาระ Manual Optimization, Server Components ทำให้ App เร็วขึ้น, Actions ทำให้จัดการ Form/Mutation ง่ายขึ้น และ Document Metadata ทำให้ไม่ต้องพึ่ง Library เพิ่ม สำหรับ React Developer ปี 2026 การเรียนรู้ Features เหล่านี้เป็นสิ่งจำเป็นอย่างยิ่ง
