ข้ามไปยังเนื้อหา

Server Components

React Server Component (RSC) รันบน server, ผลิต output ที่นั่น และ ไม่ส่ง code ไปที่ client browser ได้รับแค่ ผลลัพธ์ ไม่ใช่ตัว component นั่นให้ประโยชน์สองอย่าง: dependency ของ component (Markdown parser, database client) ไม่ไปอยู่ใน client bundle และ component เข้าถึง resource ของ server ได้ตรง ๆ

เพราะรันบน server, Server Component จึงเป็น async และ fetch data แบบ inline ได้ — ไม่ต้อง useEffect, ไม่ต้องมี loading state, ไม่ต้อง round-trip ไป client:

// Server Component — runs on the server. Note: it's an async function.
export default async function ProductPage({ id }) {
const product = await db.products.findById(id); // direct DB access, on the server
return (
<article>
<h1>{product.name}</h1>
<p>{product.description}</p>
</article>
);
}

ไม่มี 'use client' ตรงนี้ component นี้จึงเป็น Server Component: await data แล้ว return JSX; client เห็นแค่ markup ที่ render แล้วเท่านั้น

Server Component ทำเรื่อง interactive ไม่ได้ — ไม่มี useState, ไม่มี onClick, ไม่มี browser API เพราะ code นั้นไม่เคยรันใน browser เมื่อคุณต้องการ interactivity คุณข้ามไปเป็น Client Component โดยใส่ directive 'use client' ที่ด้านบนของไฟล์:

'use client';
import { useState } from 'react';
// Client Component — ships to the browser, can use state and events.
export default function AddToCart({ productId }) {
const [count, setCount] = useState(0);
return <button onClick={() => setCount((c) => c + 1)}>In cart: {count}</button>;
}

'use client' มาร์ค boundary: ไฟล์นั้นและทุกอย่างที่ไฟล์นั้น import จะกลายเป็น client code Server Component สามารถ render Client Component ได้ (server page ใส่ปุ่ม interactive ได้) แต่ทิศทางกลับกันไม่ได้แบบเดียวกัน — ทิศของ boundary สำคัญ

flowchart TB
  subgraph server["Server (never shipped)"]
    sc["Server Component
async, DB access, secrets"]
  end
  subgraph client["Client (shipped to browser)"]
    cc["Client Component
use client, useState, onClick"]
  end
  sc -->|renders + passes
serializable props| cc
server/client boundary

Server Component ส่ง props ให้ Client Component แต่ props เหล่านั้นต้อง serializable — ต้องรอดจากการถูกส่งข้าม network ในรูปของ data:

  • ✅ string, number, boolean, plain object/array, JSX และ promise (client resolve ด้วย use())
  • ❌ function (event handler), class instance หรืออะไรที่ถือ live state — serialize แล้วส่งไม่ได้
// Server Component passes a promise across the boundary:
export default function Page() {
const commentsPromise = fetchComments(); // not awaited here
return <Comments commentsPromise={commentsPromise} />; // Client resolves it with use()
}

ข้อควรรู้ตามจริง: คุณไม่ได้ Server Components จาก react เปล่า ๆ + bundler RSC ต้องใช้ framework หรือ build setup ที่เข้าใจการแยก server/client และ serialize boundary ได้ — ในทางปฏิบัติคือ Next.js (App Router) และ framework อื่นที่รองรับ RSC แนวคิดเป็นของ React ส่วนการ wiring เป็นของ framework

อะไรคือจุดเด่นของ React Server Component?
Server Component fetch data อย่างไร?
directive `use client` มาร์คอะไร?
prop ใดที่ส่งจาก Server Component ไป Client Component ไม่ได้?