React Server Components là gì và tại sao nó thay đổi cách chúng ta viết React?
Giới thiệu
Nếu bạn đang làm việc với Next.js 13+ hoặc Next.js 15, chắc hẳn bạn đã nghe đến khái niệm React Server Components (RSC). Đây không phải là một tính năng nhỏ — nó thay đổi cơ bản cách chúng ta tư duy về việc fetch data và render UI trong React.
Server Components là gì?
Trước đây, mọi React component đều chạy trên client (trình duyệt). Server Components là loại component chỉ chạy trên server — chúng không bao giờ được shipped xuống client, không có JavaScript bundle, và có thể trực tiếp truy cập database, file system, hay bất kỳ server-side resource nào.
// ServerComponent.tsx - Chạy trên server, KHÔNG gửi JS xuống client
async function BlogPost({ id }: { id: string }) {
// Trực tiếp query database - không cần fetch API
const post = await db.posts.findById(id)
return (
<article>
<h1>{post.title}</h1>
<p>{post.content}</p>
</article>
)
}
Khác gì so với Client Components?
- Server Components: Render trên server, không có state, không có event handlers, không dùng hooks như useState/useEffect. Nhưng có thể async/await trực tiếp.
- Client Components: Render trên client, có đầy đủ interactivity — state, effects, event listeners. Cần thêm
"use client"ở đầu file.
Khi nào dùng Server Components?
Dùng Server Components khi bạn cần:
- Fetch data từ database hoặc API (không expose ra client)
- Render static content không cần interactivity
- Giảm bundle size — component không được ship xuống browser
- Access server-side resources như filesystem, env secrets
Khi nào dùng Client Components?
Dùng "use client" khi bạn cần:
- State và interactivity (
useState,useReducer) - Event listeners (
onClick,onChange) - Browser APIs (
localStorage,window) - Third-party libraries cần DOM access
Pattern thực tế: Server shell + Client leaf
Pattern phổ biến nhất là để Server Component làm "vỏ" — fetch data, pass xuống Client Component để xử lý interactivity:
// page.tsx (Server Component)
export default async function ProfilePage() {
const profile = await fetchProfile() // fetch trực tiếp
return <ProfileClient profile={profile} /> // pass data xuống
}
// ProfileClient.tsx (Client Component)
"use client"
export function ProfileClient({ profile }: { profile: Profile }) {
const [isEditing, setIsEditing] = useState(false)
// ... UI với interactivity
}
Kết luận
React Server Components không phải để thay thế Client Components — chúng bổ sung cho nhau. Hiểu rõ ranh giới giữa hai loại sẽ giúp bạn xây dựng app nhanh hơn, ít JavaScript hơn, và trải nghiệm người dùng tốt hơn. Trong Next.js 15, mọi component mặc định đều là Server Component — hãy tận dụng điều đó.