React 19 có gì mới? Những thay đổi dev frontend cần biết trong 2026

16 giờ trước · 7 phút đọc
Mình từng viết 40 dòng chỉ để handle một cái form
Hồi React 18, mỗi lần viết form submit là mình lại copy-paste cái pattern quen thuộc: useState cho loading, useState cho error, preventDefault, try/catch, finally set loading về false. Nghe quen không?
React 19 ra đời để giải quyết đúng cái vòng lặp đó. Bản stable phát hành cuối 2024, và đến 2026 đây là nền tảng chính cho bất kỳ dự án React mới nào. Trọng tâm không phải là thay đổi cách render nội bộ, mà là giảm boilerplate thực tế mà mình viết mỗi ngày.
Bài này mình sẽ đi qua từng thay đổi với code trước/sau thật cụ thể, giải thích khi nào nên dùng, và cuối bài có migration guide để upgrade từ React 18 mà không làm vỡ app.
React 19 tập trung vào developer experience, không chỉ tối ưu render
Actions: viết form async không còn cần boilerplate
Đây là thay đổi mình thích nhất trong React 19. Thay vì tự quản lý loading state và gọi preventDefault, bạn truyền thẳng một async function vào form action. React lo phần còn lại.
Trước React 19:
React 19:
Ít state hơn, ít lỗi hơn - đặc biệt khi quên set loading về false
Code React 19 ngắn hơn không chỉ vì ít dòng - mà vì bạn không còn tự quản lý một đống state có thể bị out-of-sync. Khi action throw error, React tự xử lý. Khi form reset sau submit, React cũng lo.
Dùng Actions khi nào? Form đăng nhập/đăng ký, CRUD admin, checkout, comment, profile update - bất kỳ form nào có async submit và cần pending state rõ ràng.
useActionState và useFormStatus: quản lý state submit sạch hơn
Hai hook này thường đi kèm nhau. useActionState gom toàn bộ submit flow vào một chỗ, còn useFormStatus cho phép component con đọc trạng thái form mà không cần prop drilling.
useActionState
Thay vì nhiều useState rời rạc quanh một form, bạn có một hook duy nhất:
State, action, pending flag - tất cả từ một hook. Khi form submit thành công hay thất bại, state được cập nhật tự động.
useFormStatus
Vấn đề cũ: nút Submit nằm trong component con, nhưng không biết form cha đang pending hay không nếu không truyền props thủ công.
useFormStatus đọc context form cha - không cần truyền props từng cấp
Lợi ích thực tế: bạn xây một SubmitButton component dùng chung cho toàn app. Nó tự biết khi nào disable, khi nào show spinner - không cần ai nhớ truyền loading prop.
Một điểm cần lưu ý: useFormStatus chỉ đọc được trạng thái của form cha gần nhất trong DOM tree. Nếu SubmitButton không nằm trong <form>, hook sẽ trả về { pending: false } mà không báo lỗi.
useOptimistic: UI phản hồi trước khi server xác nhận
Optimistic UI là kỹ thuật update giao diện ngay lập tức, rồi reconcile với dữ liệu thật sau khi server trả về. Trước React 19, bạn phải tự quản lý temporary state, rollback khi lỗi - khá cồng kềnh.
useOptimistic giải quyết pattern này:
Người dùng thấy kết quả ngay, không cần chờ server round-trip
Dùng khi nào? Like, reaction, add to cart, reorder danh sách, đánh dấu đã đọc - bất kỳ action nào người dùng expect kết quả ngay và rollback được nếu server fail.
Trade-off cần nhớ: nếu server fail thường xuyên, optimistic UI có thể gây confuse hơn là helpful. Hook này phù hợp khi tỷ lệ thành công cao và rollback ít xảy ra.
ref như một prop: bỏ forwardRef cho component mới
Trước React 19, mỗi khi component function cần expose DOM node ra ngoài (để focus, measure, scroll...), bạn bắt buộc phải bọc bằng forwardRef. Ceremony thừa, đặc biệt khi xây design system với hàng chục wrapper component.
Trước React 19:
React 19:
forwardRef vẫn chạy, nhưng code mới không cần dùng nữa
Lợi ích rõ nhất khi xây design system: Button, Input, Modal, Tooltip - tất cả cần expose ref ra ngoài để parent có thể focus/measure. Với cách cũ, từng component phải bọc forwardRef. Với React 19, đơn giản như nhận prop thường.
Lưu ý quan trọng: forwardRef vẫn hoạt động bình thường trong React 19, không bị deprecate đột ngột. Codebase cũ không cần migrate ngay - chỉ áp dụng cách mới cho component viết mới.
Server Components: render trên server, bundle nhẹ hơn
Server Components không phải khái niệm hoàn toàn mới, nhưng React 19 tiếp tục củng cố và mở rộng - đặc biệt ở các bản 2025-2026 với Context trong Server Components.
Ý tưởng cốt lõi: một phần UI render hoàn toàn trên server, không gửi JS component xuống client. Người dùng nhận HTML tĩnh cho phần đó, client chỉ nhận JS cho phần thật sự cần tương tác.
Chỉ component cần interactivity mới gửi JS xuống client
Khi nào dùng? Trang nội dung nhiều dữ liệu (dashboard, listing page, blog), phần không cần click/hover/input. Khi không dùng Server Components, toàn bộ data fetching logic vẫn chạy client-side - không sai, nhưng bundle to hơn và TTFB chậm hơn.
Nếu bạn đang dùng Next.js App Router, Server Components là mặc định - bạn đã xài rồi mà có thể chưa để ý.
