ข้อผิดพลาดของไฮเดรชัน: สาเหตุและวิธีแก้
ระบุความไม่ตรงกันระหว่าง 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 outputsuppressHydrationWarning
ใช้ 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 ในทันที — ไม่ต้องติดตั้งในเครื่องของคุณ
บทเรียนทั้งหมดในหลักสูตรนี้
- เบื้องหลังการทำงานของ React SSR
- ข้อผิดพลาดของไฮเดรชัน: สาเหตุและวิธีแก้
- ไฮเดรชันแบบเลือกและ HTML แบบสตรีม
- รูปแบบสถาปัตยกรรม Islands