Server Component và Client Component

4 min read

Điểm SEO 71/100 chưa đạt yêu cầu, cần được trên 80 điểm

Nếu như chỉ quen thuộc với ReactJS, hẳn bạn sẽ khá lạ lẫm khi nghe tới hai khái niệm Server Component và Client Component của Next.js.

Trong bài viết này, chúng ta sẽ cùng nhau khám phá về công dụng, cách hoạt động cũng như khi nào cần sử dụng hai loại component này trong dự án Next.js.

1. Khái niệm

1.1. Server Components

Server Components là các component React chỉ chạy hoàn toàn trên server. Server Component là component mặc định của NextJs kể từ phiên bản 13 với App Router

1.2. Client Components

Là các component tương tự component trong React truyền thống, được render trực tiếp trên trình duyệt Client. Để biến một Server Component thành Client Component, ta cần cho NextJs biết bằng cách thêm ‘use client’ vào đầu

2. Cách thức hoạt động của Server, Client Component

Để hiểu rõ cách thức hoạt động của hai loại component này. Ta cùng tìm hiểu và phân tích sơ đồ hoạt động sau

Bước 1: User Request

Hành động: Mọi thứ bắt đầu khi người dùng thực hiện một hành động trong Client Browser, chẳng hạn như gõ một URL vào thanh địa chỉ hoặc nhấp vào một thẻ <Link>.
Kết quả: Một HTTP Request được gửi từ trình duyệt đến Next.js Server.

Bước 2: Router xử lý (App Router)

Hành động: Next.js Server nhận được yêu cầu. App Router sẽ phân tích URL (ví dụ: /products/123) để xác định component nào cần được render cho route đó
(ví dụ: file app/products/[id]/page.js).

Bước 3: Fetch Data

Hành động: Đây là một trong những bước quan trọng nhất của Server Components. Server Component, vì đang chạy hoàn toàn trên server, có thể truy cập trực tiếp và an toàn vào các nguồn dữ liệu (Data Sources).

Ví dụ: Nó có thể gọi thẳng đến Database, các External APIs, hoặc đọc file từ File System bằng cách sử dụng async/await.

Lợi ích: Các thông tin nhạy cảm như chuỗi kết nối database, API keys không bao giờ bị gửi về trình duyệt.

Kết quả: Dữ liệu được trả về (Return Data) cho Server Component để xử lý ở bước tiếp theo.

Bước 4: Tạo RSC Payload

Hành động: Sau khi có dữ liệu, Server Component thực hiện các công việc chính của nó:

  • Chạy trên server: Toàn bộ logic được thực thi trên máy chủ.
  • Không có JavaScript ở client: Mã nguồn của component này không được đóng gói để gửi về trình duyệt.

Kết quả: Server Component KHÔNG render ra HTML trực tiếp. Thay vào đó, nó tạo ra một định dạng dữ liệu đặc biệt gọi là RSC Payload (Serialized React Element Tree). Đây là một “bản mô tả” cây giao diện dưới dạng text, rất gọn nhẹ. Nó chứa:

  • Cấu trúc UI của Server Component.
  • Các placeholders chỉ định vị trí của các Client Components sẽ được chèn vào.

Bước 5: HTML Generation

Hành động: Next.js trên server lấy RSC Payload đã được tạo ở bước 4 và sử dụng nó để tạo ra file HTML cuối cùng.

  • Trong quá trình này, các Client Components cũng được render lần đầu trên server (Server-Side Rendering – SSR) để tạo ra HTML tĩnh ban đầu. Điều này đảm bảo người dùng thấy giao diện ngay lập tức.
  • Streaming support: Next.js có thể gửi HTML theo từng phần (stream) về trình duyệt, giúp trang hiển thị nhanh hơn thay vì phải chờ toàn bộ trang render xong.

Bước 6: Trả về Client (HTTP Response)

Hành động: Server gửi một HTTP Response về cho trình duyệt. Gói phản hồi này chứa:

  • HTML content: Toàn bộ HTML của trang.
  • Client-side JavaScript bundle: Chỉ là các file JS của những Client Component được sử dụng trên trang.

Kết quả cuối cùng:

  • Trình duyệt nhận HTML và hiển thị nó ngay lập tức.
  • Sau đó, nó tải và thực thi các file JavaScript.
  • Quá trình Hydration diễn ra: Trình duyệt gắn các state và sự kiện (onClick, onChange) vào các Client Component được gửi tới, khiến chúng có thể tương tác.

3. Sử dụng Server, Client Component khi nào?

Trường hợpServer ComponentClient Component
Lấy dữ liệu tĩnh
Cần tương tác
Cập nhật trực tiếp (Chat, Thông báo, …)
Dữ liệu cần bảo mật
Browser APIs (localStorage, geolocation, …)
Component chỉ hiển thị, không có tương tác
Sử dụng thư viện chỉ chạy ở trình duyệt (Zustand, Redux, …)

4. Ví dụ trực quan

Ví dụ, Component Page là Server Component có chức năng lấy dữ liệu về bài đăng và truyền dữ liệu đó dưới dạng props cho LikeButton để xử lý tương tác phía Client.

//app/[id]/page.tsx

import LikeButton from '@/app/ui/like-button'
import { getPost } from '@/lib/data'
 
export default async function Page({ params }: { params: { id: string } }) {
  const post = await getPost(params.id)
 
  return (
    <div>
      <main>
        <h1>{post.title}</h1>
        {/* ... */}
        <LikeButton likes={post.likes} />
      </main>
    </div>
  )
}
//app/ui/like-button.tsx

'use client'
 
import { useState } from 'react'
 
export default function LikeButton({ likes }: { likes: number }) {
  // ...
}
Avatar photo

Dựng front-end bằng Clean Architecture

Khi nhắc đến Clean Architecture, nhiều người thường chỉ nghĩ đến backend – nơi cần cấu trúc rõ ràng để quản lý nghiệp vụ...
Avatar photo Toan Nguyen Thai
5 min read

Khám phá Monorepo: Cách bứt phá quản lý mã…

Trong thế giới phát triển phần mềm hiện đại, việc quản lý mã nguồn đang trở nên phức tạp hơn bao giờ hết. Các...
Avatar photo dan.nguyenhai@ncc.asia
4 min read

Công nghệ Lượng tử và Bước đột phá của…

“Công nghệ lượng tử không chỉ giúp hệ thống tính toán xử lý nhanh hơn, nó còn giúp con người thay đổi cách nhìn...
Avatar photo Ngọ Văn Trọng
5 min read

Leave a Reply

Your email address will not be published. Required fields are marked *