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

ข้อผิดพลาดของไฮเดรชัน: สาเหตุและวิธีแก้

ระบุความไม่ตรงกันระหว่าง HTML ฝั่งเซิร์ฟเวอร์และฝั่งไคลเอ็นต์ แล้วแก้ไขด้วย suppressHydrationWarning

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

ข้อผิดพลาดการไฮเดรตคืออะไร

ข้อผิดพลาดการไฮเดรตเกิดขึ้นเมื่อ HTML ที่เรนเดอร์โดยเซิร์ฟเวอร์ของ React ไม่ตรงกับ DOM เสมือนที่ React คาดหวังบนไคลเอ็นต์ React จะบันทึกคำเตือนและเรนเดอร์คอมโพเนนต์ใหม่ตั้งแต่ต้น ทำให้เกิดภาพกะพริบ

สาเหตุทั่วไป 1: ค่าสุ่ม

การใช้ Math.random(), Date.now() หรือ crypto.randomUUID() ระหว่างการเรนเดอร์จะสร้างค่าที่แตกต่างกันบนเซิร์ฟเวอร์และไคลเอ็นต์

// Bad — different on server vs client:
<div id={Math.random().toString()}>...</div>

// Fix — use useId() (stable across server/client):
import { useId } from 'react';
function Component() {
  const id = useId();
  return <div id={id}>...</div>;
}

สาเหตุทั่วไป 2: ส่วนติดต่อที่มีเฉพาะในเบราว์เซอร์

การอ่าน localStorage, window.innerWidth หรือ navigator ระหว่างการเรนเดอร์อาจทำให้เซิร์ฟเวอร์หยุดทำงานหรือสร้างค่าที่แตกต่างกัน

// Bad — localStorage doesn't exist on server:
<div>{localStorage.getItem('theme')}</div>

// Fix — read in useEffect (client-only):
const [theme, setTheme] = useState('light');
useEffect(() => {
  setTheme(localStorage.getItem('theme') ?? 'light');
}, []);

สาเหตุทั่วไป 3: การจัดรูปแบบวันที่และเวลา

การจัดรูปแบบวันที่ตามภูมิภาคจะคืนค่าสตริงที่แตกต่างกันบนเซิร์ฟเวอร์ (ภูมิภาคของ UTC/Node) และไคลเอ็นต์ (ภูมิภาคของเบราว์เซอร์)

// Risky — locale may differ:
<time>{new Date().toLocaleDateString()}</time>

// Fix — use a consistent locale:
<time>{new Date().toLocaleDateString('en-US', { timeZone: 'UTC' })}</time>

สาเหตุทั่วไป 4: การซ้อนแท็ก HTML ไม่ถูกต้อง

React สร้าง HTML ฝั่งไคลเอ็นต์จาก DOM เสมือน แต่การซ้อนแท็ก HTML ที่ไม่ถูกต้อง (เช่น <p> ไว้ภายใน <p>) ทำให้เบราว์เซอร์ปรับโครงสร้าง DOM แตกต่างกันและทำให้เกิดความไม่ตรงกัน

// Bad — browser auto-closes the nested <p>:
<p>Outer <p>Inner</p> text</p>

// Fix — use <div> or correct semantic elements:
<div>Outer <p>Inner</p> text</div>

สาเหตุทั่วไป 5: การเรนเดอร์แบบมีเงื่อนไขตามสถานะ

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

// Bad — server renders 'Guest', client re-renders 'Alice' immediately:
<h1>{user?.name ?? 'Guest'}</h1>

// Fix — use a mounted guard to defer client-only rendering:
const [mounted, setMounted] = useState(false);
useEffect(() => setMounted(true), []);
if (!mounted) return <h1>Guest</h1>; // match server output

suppressHydrationWarning

ใช้ suppressHydrationWarning กับองค์ประกอบที่ความไม่ตรงกันเกิดขึ้นโดยตั้งใจ (เช่น การจัดรูปแบบการประทับเวลาฝั่งไคลเอ็นต์) คำสั่งนี้จะระงับคำเตือนเฉพาะองค์ประกอบนั้น

<time suppressHydrationWarning dateTime={isoDate}>
  {new Date(isoDate).toLocaleString()}
</time>

การนำเข้าแบบไดนามิกโดยปิด SSR

ใน Next.js ใช้ dynamic(fn, { ssr: false }) เพื่อป้องกันไม่ให้คอมโพเนนต์เรนเดอร์บนเซิร์ฟเวอร์โดยสิ้นเชิง ซึ่งจะกำจัดความไม่ตรงกันระหว่างการไฮเดรตสำหรับคอมโพเนนต์ที่มีเฉพาะบนไคลเอ็นต์

import dynamic from 'next/dynamic';

const ClientOnlyChart = dynamic(() => import('./Chart'), { ssr: false });

export default function Dashboard() {
  return <ClientOnlyChart />; // only renders in the browser
}

การแก้ไขข้อผิดพลาดการไฮเดรต

React 18 จะบันทึกข้อความข้อผิดพลาดการไฮเดรตโดยละเอียดในโหมดพัฒนา ซึ่งแสดงโหนด DOM ที่ไม่ตรงกันอย่างชัดเจน ใช้ DevTools ของเบราว์เซอร์เพื่อตรวจสอบ HTML จากเซิร์ฟเวอร์เทียบกับต้นไม้ของ React

useId สำหรับรหัสที่คงที่

useId() สร้างรหัสที่ไม่ซ้ำและคงที่ ซึ่งตรงกันระหว่างการเรนเดอร์บนเซิร์ฟเวอร์และไคลเอ็นต์ ใช้สำหรับคู่ id/htmlFor และแอตทริบิวต์ ARIA

function FormInput({ label }: { label: string }) {
  const id = useId();
  return (
    <div>
      <label htmlFor={id}>{label}</label>
      <input id={id} />
    </div>
  );
}

การทดสอบข้อผิดพลาดการไฮเดรต

เรียกใช้แอป Next.js ในโหมดพัฒนา (npm run dev) และดูคอนโซลของเบราว์เซอร์ ความไม่ตรงกันระหว่างการไฮเดรตจะแสดงเป็นคำเตือนสีแดงพร้อมร่องรอยสแต็กของคอมโพเนนต์

ตรวจสอบความเข้าใจ

วิธีแก้ไขที่ดีที่สุดสำหรับคอมโพเนนต์ที่เรนเดอร์แตกต่างกันบนเซิร์ฟเวอร์และไคลเอ็นต์เนื่องจากอ่านค่าจาก localStorage คืออะไร

สรุปทบทวน

ความไม่ตรงกันระหว่างการไฮเดรตเกิดจากค่าสุ่ม ส่วนติดต่อที่มีเฉพาะในเบราว์เซอร์ การจัดรูปแบบตามภูมิภาค การซ้อนแท็ก HTML ที่ไม่ถูกต้อง และการเรนเดอร์แบบมีเงื่อนไขเฉพาะไคลเอ็นต์ แก้ไขด้วย useId(), useEffect สำหรับสถานะเฉพาะไคลเอ็นต์ suppressHydrationWarning สำหรับความแตกต่างที่ตั้งใจ และ dynamic({ ssr: false }) สำหรับคอมโพเนนต์เฉพาะไคลเอ็นต์

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

บทเรียน “ข้อผิดพลาดของไฮเดรชัน: สาเหตุและวิธีแก้” ฟรีหรือไม่

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

คุณจะเรียนรู้อะไรในบทเรียน “ข้อผิดพลาดของไฮเดรชัน: สาเหตุและวิธีแก้”

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

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

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

บทเรียน “ข้อผิดพลาดของไฮเดรชัน: สาเหตุและวิธีแก้” ใช้เวลานานแค่ไหน

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

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

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

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

  1. เบื้องหลังการทำงานของ React SSR
  2. ข้อผิดพลาดของไฮเดรชัน: สาเหตุและวิธีแก้
  3. ไฮเดรชันแบบเลือกและ HTML แบบสตรีม
  4. รูปแบบสถาปัตยกรรม Islands
← กลับไปที่ React Academy