0Pricing
React Academy · บทเรียน

คอมโพเนนต์ฝั่งเซิร์ฟเวอร์กับฝั่งไคลเอ็นต์ใน Next.js

ตัดสินใจว่าจะเพิ่ม 'use client' เมื่อใด และประกอบโครงสร้างฝั่งเซิร์ฟเวอร์กับฝั่งไคลเอ็นต์อย่างไร

คอมโพเนนต์ฝั่งเซิร์ฟเวอร์กับฝั่งไคลเอ็นต์ใน Next.js เป็นบทเรียน React Academy ฟรีบน CoddyKit นี่คือบทเรียนที่ 2 จากทั้งหมด 4 บทเรียน คุณสามารถอ่านบทเรียนทั้งหมดด้านล่างฟรี — จากนั้นลองปฏิบัติด้วยตัวคุณเองในเบราว์เซอร์พร้อมตัวแก้ไขโค้ดในตัวและติวเตอร์ AI ตลอด 24/7 บทเรียนนี้เป็นส่วนหนึ่งของเส้นทางการเรียน React Academy และความก้าวหน้าของคุณจะซิงค์ข้ามเว็บและแอป CoddyKit คอร์ส React Academy มีบทเรียนทั้งหมด 4 บทเรียน

ค่าเริ่มต้น: คอมโพเนนต์ฝั่งเซิร์ฟเวอร์

ใน App Router คอมโพเนนต์ทั้งหมดเป็น คอมโพเนนต์ฝั่งเซิร์ฟเวอร์ โดยค่าเริ่มต้น คอมโพเนนต์เหล่านี้จะแสดงผลบนเซิร์ฟเวอร์ ไม่มี JavaScript ฝั่งไคลเอนต์เลย และสามารถเข้าถึงฐานข้อมูล ตัวแปรสภาพแวดล้อม และระบบไฟล์ได้โดยตรง

การเลือกใช้คอมโพเนนต์ฝั่งไคลเอนต์

เพิ่ม 'use client' ที่ด้านบนสุดของไฟล์เพื่อกำหนดให้เป็นคอมโพเนนต์ฝั่งไคลเอนต์ การนำเข้าทั้งหมดของคอมโพเนนต์นั้นจะกลายเป็นฝั่งไคลเอนต์ด้วย — นี่คือการสร้างขอบเขตฝั่งไคลเอนต์

'use client';

import { useState } from 'react';

export function Counter() {
  const [count, setCount] = useState(0);
  return <button onClick={() => setCount(c => c + 1)}>{count}</button>;
}

สิ่งที่คอมโพเนนต์ฝั่งเซิร์ฟเวอร์ทำได้

คอมโพเนนต์ฝั่งเซิร์ฟเวอร์สามารถ await การดึงข้อมูลภายในโค้ดได้ อ่านตัวแปรสภาพแวดล้อม เข้าถึงระบบไฟล์ และนำเข้าแพ็กเกจขนาดใหญ่ที่ใช้เฉพาะเซิร์ฟเวอร์ได้โดยไม่ทำให้ชุดโค้ดฝั่งไคลเอนต์มีขนาดเพิ่มขึ้น

// app/products/page.tsx — Server Component
export default async function ProductsPage() {
  const products = await db.query('SELECT * FROM products');
  return (
    <ul>
      {products.map(p => <li key={p.id}>{p.name}</li>)}
    </ul>
  );
}

สิ่งที่คอมโพเนนต์ฝั่งเซิร์ฟเวอร์ทำไม่ได้

คอมโพเนนต์ฝั่งเซิร์ฟเวอร์ไม่สามารถใช้ฮุก (useState, useEffect) API ของเบราว์เซอร์ หรือตัวจัดการเหตุการณ์ได้ สิ่งเหล่านี้ต้องใช้ 'use client'

การประกอบคอมโพเนนต์ฝั่งเซิร์ฟเวอร์และฝั่งไคลเอนต์

ส่งผลลัพธ์ของคอมโพเนนต์ฝั่งเซิร์ฟเวอร์เป็นพร็อพหรือองค์ประกอบลูกให้คอมโพเนนต์ฝั่งไคลเอนต์ แนวทางหลักคือ เก็บการดึงข้อมูลไว้ในคอมโพเนนต์ฝั่งเซิร์ฟเวอร์ และเก็บการโต้ตอบไว้ในคอมโพเนนต์ฝั่งไคลเอนต์

// Server Component (no 'use client')
async function ProductPage({ id }) {
  const product = await getProduct(id); // direct DB call
  return <AddToCartButton product={product} />; // client component
}

// Client Component
'use client';
function AddToCartButton({ product }) {
  const [added, setAdded] = useState(false);
  return <button onClick={() => { addToCart(product); setAdded(true); }}>{added ? 'Added!' : 'Add to cart'}</button>;
}

การส่งองค์ประกอบลูกจากเซิร์ฟเวอร์ไปยังไคลเอนต์

คอมโพเนนต์ฝั่งเซิร์ฟเวอร์สามารถส่ง JSX เป็น children ให้คอมโพเนนต์ฝั่งไคลเอนต์ได้ องค์ประกอบลูกจะยังคงแสดงผลบนเซิร์ฟเวอร์ ส่วนตัวครอบฝั่งไคลเอนต์จะเพิ่มการโต้ตอบให้

// Client wrapper — Modal with open/close state
'use client';
function Modal({ children }) {
  const [open, setOpen] = useState(false);
  return (
    <>
      <button onClick={() => setOpen(true)}>Open</button>
      {open && <dialog>{children}</dialog>}
    </>
  );
}

// Server Component — passes server-fetched content into client modal
async function Page() {
  const content = await fetchContent();
  return <Modal><ServerRenderedContent data={content} /></Modal>;
}

ขอบเขตฝั่งไคลเอนต์

การเพิ่ม 'use client' จะทำให้ไฟล์และการนำเข้าองค์ประกอบลูกทั้งหมดเป็นฝั่งไคลเอนต์ หากต้องการให้องค์ประกอบลูกยังเป็นคอมโพเนนต์ฝั่งเซิร์ฟเวอร์ ให้ส่งองค์ประกอบนั้นเป็นพร็อพหรือช่องแทนการนำเข้าโดยตรง

รูปแบบการดึงข้อมูล

ดึงข้อมูลในคอมโพเนนต์ฝั่งเซิร์ฟเวอร์แล้วส่งต่อข้อมูลลงไป หลีกเลี่ยงการดึงข้อมูลในคอมโพเนนต์ฝั่งไคลเอนต์เมื่อทำได้ — เพราะจะเพิ่มขนาดชุดโค้ดฝั่งไคลเอนต์และทำให้ตรรกะฝั่งเซิร์ฟเวอร์ซ้ำซ้อน

// Good: fetch in server, pass to client
async function Page() {
  const user = await getUser();
  return <UserProfile user={user} />; // client component
}

// Avoid: fetch in client
'use client';
function UserProfile() {
  const { data } = useSWR('/api/user', fetcher); // network request from browser
}

ยูทิลิตีที่ใช้เฉพาะเซิร์ฟเวอร์

แพ็กเกจ server-only จะแจ้งข้อผิดพลาดระหว่างการสร้าง หากมีการนำเข้าโมดูลที่ใช้เฉพาะเซิร์ฟเวอร์เข้าไปในคอมโพเนนต์ฝั่งไคลเอนต์โดยไม่ตั้งใจ

// lib/db.ts
import 'server-only'; // throws at build time if imported in 'use client' file

export const db = createDbClient(process.env.DB_URL);

การแชร์สถานะระหว่างเซิร์ฟเวอร์และไคลเอนต์

คอมโพเนนต์ฝั่งเซิร์ฟเวอร์ไม่สามารถเก็บสถานะได้ หากต้องการแชร์สถานะจากการดึงข้อมูลบนเซิร์ฟเวอร์ไปยังคอมโพเนนต์ฝั่งไคลเอนต์ที่มีการโต้ตอบ ให้ส่งสถานะนั้นเป็นพร็อพในการแสดงผลครั้งแรก แล้วจัดการการอัปเดตบนไคลเอนต์

เมื่อใดควรเพิ่ม use client

เพิ่ม 'use client' เมื่อจำเป็นต้องใช้สิ่งต่อไปนี้: ฮุก (useState, useEffect), เหตุการณ์ของเบราว์เซอร์ (onClick), API ของเบราว์เซอร์ (localStorage, window) หรือไลบรารีฝั่งไคลเอนต์จากบุคคลที่สาม

ตรวจสอบอย่างรวดเร็ว

คุณต้องเพิ่มสิ่งใดที่ด้านบนสุดของไฟล์เพื่อใช้ useState หรือ onClick ใน App Router ของ Next.js

สรุป

คอมโพเนนต์ทั้งหมดของ App Router เป็นคอมโพเนนต์ฝั่งเซิร์ฟเวอร์โดยค่าเริ่มต้น — ไม่มีชุดโค้ด JS และเข้าถึงข้อมูลได้โดยตรง เพิ่ม 'use client' เฉพาะจุดที่ต้องการการโต้ตอบ ประกอบคอมโพเนนต์โดยส่งข้อมูลที่ดึงจากเซิร์ฟเวอร์เป็นพร็อพหรือองค์ประกอบลูกให้ตัวครอบฝั่งไคลเอนต์ และรักษาขอบเขตฝั่งไคลเอนต์ให้ใกล้กับใบไม้ของต้นไม้คอมโพเนนต์มากที่สุด

คำถามที่พบบ่อย

บทเรียน “คอมโพเนนต์ฝั่งเซิร์ฟเวอร์กับฝั่งไคลเอ็นต์ใน Next.js” ฟรีหรือไม่

ใช่ — ข้อความเต็มของ “คอมโพเนนต์ฝั่งเซิร์ฟเวอร์กับฝั่งไคลเอ็นต์ใน Next.js” ฟรีให้อ่านที่นี่บนเว็บ เพื่อปฏิบัติแบบโต้ตอบ (ตัวแก้ไขโค้ดในตัวและติวเตอร์ AI ตลอด 24/7) และปลดล็อคส่วนที่เหลือของคอร์ส React Academy ให้อัปเกรดเป็น CoddyKit PRO คอร์ส React Academy มีบทเรียนทั้งหมด 4 บทเรียน

คุณจะเรียนรู้อะไรในบทเรียน “คอมโพเนนต์ฝั่งเซิร์ฟเวอร์กับฝั่งไคลเอ็นต์ใน Next.js”

ตัดสินใจว่าจะเพิ่ม 'use client' เมื่อใด และประกอบโครงสร้างฝั่งเซิร์ฟเวอร์กับฝั่งไคลเอ็นต์อย่างไร คุณปฏิบัติ React Academy ด้วยโค้ดที่ใช้งานได้จริงที่คุณเรียกใช้โดยตรงในเบราว์เซอร์ และติวเตอร์ AI ตลอด 24/7 ตอบคำถามของคุณขณะที่คุณไปผ่านบทเรียน

คุณต้องมีประสบการณ์ก่อนที่จะเริ่มเรียน React Academy หรือไม่

ไม่จำเป็นต้องมีประสบการณ์มาก่อน React Academy บน CoddyKit ออกแบบมาสำหรับผู้เริ่มต้นไปจนถึงผู้เรียนขั้นสูง คุณสามารถเริ่มต้นที่นี่หรือเริ่มจากตัวแรกและเรียนด้วยความเร็วของคุณเอง นี่คือบทเรียนที่ 2 จากทั้งหมด 4 บทเรียน

บทเรียน “คอมโพเนนต์ฝั่งเซิร์ฟเวอร์กับฝั่งไคลเอ็นต์ใน Next.js” ใช้เวลานานแค่ไหน

บทเรียน CoddyKit ส่วนใหญ่ใช้เวลาประมาณ 5–10 นาที แต่ละบทเรียนจึงสั้นและเป็นแบบโต้ตอบ คุณสามารถก้าวหน้าอย่างต่อเนื่องและกลับมาเรียนต่อจากตรงที่เพิ่งหยุดบนเว็บและแอปได้เลย

ฉันเขียนและรันโค้ดในบทเรียน React Academy นี้ได้ไหม

ได้ บทเรียน React Academy ทุกบทมีตัวแก้ไขโค้ดในตัว คุณจึงเขียนและรันโค้ดจริงได้เลยในเบราว์เซอร์ และได้รับข้อเสนอแนะจาก AI ในทันที — ไม่ต้องติดตั้งในเครื่องของคุณ

บทเรียนทั้งหมดในหลักสูตรนี้

  1. รูปแบบการตั้งชื่อไฟล์ของ App Router
  2. คอมโพเนนต์ฝั่งเซิร์ฟเวอร์กับฝั่งไคลเอ็นต์ใน Next.js
  3. เส้นทางแบบไดนามิกและกลุ่มเส้นทาง
  4. Metadata API และ SEO ใน App Router
← กลับไปที่ React Academy