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: Deep Dive vào Architecture
#react#server-components#nextjs#performance

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

Bài Viết Liên Quan

Bình luận(0)

Đăng nhập để tham gia thảo luận