React Server Components: Deep Dive vào Architecture
Hiểu rõ cách React Server Components hoạt động, khi nào dùng Client vs Server Component và các patterns phổ biến.
Minh Dev05 tháng 12 202415 phút4 thẻ
Share:
#react#server-components#nextjs#performance
Nội dung chính
React Server Components là gì?
React Server Components (RSC) là một paradigm mới cho phép render components trực tiếp trên server, không cần JavaScript ở phía client.
Key insight: Server Components không bao giờ re-render. Chúng chạy một lần trên server và gửi HTML + minimal data về client.
Server vs Client Components
tsx
// Server Component (mặc định trong Next.js App Router)
// Không có 'use client' directive
async function PostList() {
// Có thể fetch data trực tiếp — không cần useEffect!
const posts = await db.posts.findMany()
return (
<ul>
{posts.map(post => (
<li key={post.id}>{post.title}</li>
))}
</ul>
)
}
// Client Component
'use client'
import { useState } from 'react'
function LikeButton({ postId }: { postId: string }) {
const [liked, setLiked] = useState(false)
return (
<button onClick={() => setLiked(!liked)}>
{liked ? '❤️ Liked' : '🤍 Like'}
</button>
)
}Khi nào dùng gì?
Dùng Server Components khi:
- Fetch data từ database hoặc API
- Truy cập filesystem, environment variables, secrets
- Render large dependencies mà không muốn ship về client
Dùng Client Components khi:
- Cần
useState,useReducer,useEffect - Cần event handlers (onClick, onChange...)
- Cần browser APIs (localStorage, window...)
- Cần React Context
Composing Server và Client Components
tsx
// page.tsx (Server Component)
import { Suspense } from 'react'
import { PostList } from './post-list' // Server Component
import { SearchBar } from './search-bar' // Client Component
export default async function Page() {
return (
<div>
{/* Client Component trong Server Component — OK */}
<SearchBar />
{/* Wrap async server components với Suspense */}
<Suspense fallback={<PostListSkeleton />}>
<PostList />
</Suspense>
</div>
)
}Truyền Server Components vào Client Components
tsx
// ClientWrapper.tsx
'use client'
import { useState } from 'react'
// ✅ ĐÚNG: nhận children là prop
export function ClientWrapper({ children }: { children: React.ReactNode }) {
const [isOpen, setIsOpen] = useState(false)
return (
<div>
<button onClick={() => setIsOpen(!isOpen)}>Toggle</button>
{isOpen && children}
</div>
)
}
// page.tsx (Server Component)
import { ClientWrapper } from './client-wrapper'
import { ServerContent } from './server-content'
export default function Page() {
return (
// ServerContent được tạo trong Server context
// nhưng được hiển thị trong Client context — OK!
<ClientWrapper>
<ServerContent />
</ClientWrapper>
)
}Data Fetching Patterns
tsx
// Sequential fetching (chậm)
async function Sequential() {
const user = await fetchUser() // 200ms
const posts = await fetchPosts(user.id) // 300ms
// Total: 500ms
return <div>...</div>
}
// Parallel fetching (nhanh hơn)
async function Parallel() {
const [user, settings] = await Promise.all([
fetchUser(), // 200ms ┐
fetchSettings() // 150ms ┘ chạy song song → 200ms total
])
return <div>...</div>
}Kết Luận
React Server Components thay đổi cơ bản cách chúng ta nghĩ về rendering:
- Ít JavaScript hơn được gửi về client
- Data fetching đơn giản hơn — không cần useEffect
- Bảo mật tốt hơn — secrets không bao giờ ra client
- Performance tốt hơn — HTML được tạo sẵn trên server
RSC không phải là silver bullet — bạn vẫn cần Client Components cho interactivity. Nhưng việc hiểu ranh giới Server/Client sẽ giúp bạn xây dựng Next.js apps hiệu quả hơn.
7Lượt xem