أخطاء الإماهة: الأسباب والإصلاحات
حدّد حالات عدم التطابق بين HTML الخادم والعميل وأصلحها باستخدام suppressHydrationWarning.
أخطاء الإماهة: الأسباب والإصلاحات درس مجاني في React Academy على CoddyKit. هذا هو الدرس 2 من أصل 4. يمكنك قراءة الدرس كاملاً أدناه مجاناً — ثم تمرن عليه مباشرة في المتصفح باستخدام محرر أكواد مدمج ومدرس ذكاء اصطناعي متاح 24/7. هذا الدرس جزء من مسار التعلم في React Academy، وتقدمك يتزامن عبر الويب وتطبيق CoddyKit. تتضمن دورة React Academy 4 دروس في المجموع.
ما خطأ Hydration؟
يحدث خطأ Hydration عندما لا يتطابق 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: false
في Next.js، استخدم dynamic(fn, { ssr: false }) لمنع عرض مكوّن على الخادم بالكامل، وبذلك تتجنب عدم تطابق Hydration للمكوّنات الخاصة بالعميل.
import dynamic from 'next/dynamic';
const ClientOnlyChart = dynamic(() => import('./Chart'), { ssr: false });
export default function Dashboard() {
return <ClientOnlyChart />; // only renders in the browser
}تصحيح أخطاء Hydration
تسجّل React 18 رسائل مفصّلة عن أخطاء Hydration في وضع التطوير، وتعرض عقدة 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>
);
}اختبار أخطاء Hydration
شغّل تطبيق Next.js في وضع التطوير (npm run dev) وراقب وحدة تحكم المتصفح. تظهر حالات عدم تطابق Hydration كتحذيرات حمراء مصحوبة بتتبعات مكدس المكوّنات.
تحقق سريع
ما أفضل حل لمكوّن يعرض محتوى مختلفًا على الخادم والعميل بسبب القراءة من localStorage؟
مراجعة
ينشأ عدم تطابق Hydration بسبب القيم العشوائية، وواجهات برمجة التطبيقات الخاصة بالمتصفح، والتنسيق الحساس للإعدادات المحلية، والتداخل غير الصالح لعناصر HTML، والعرض الشرطي الخاص بالعميل. أصلح ذلك باستخدام useId()، وuseEffect للحالة الخاصة بالعميل، وsuppressHydrationWarning للاختلافات المقصودة، وdynamic({ ssr: false }) للمكوّنات الخاصة بالعميل.
الأسئلة الشائعة
هل درس «أخطاء الإماهة: الأسباب والإصلاحات» مجاني؟
نعم — نص درس «أخطاء الإماهة: الأسباب والإصلاحات» كامل متاح مجاناً هنا على الويب. لتمرينه بشكل تفاعلي (محرر أكواد مدمج ومدرس ذكاء اصطناعي متاح 24/7) وفتح باقي دورة React Academy، انتقل إلى CoddyKit PRO. تتضمن دورة React Academy 4 دروس في المجموع.
ماذا ستتعلم في «أخطاء الإماهة: الأسباب والإصلاحات»؟
حدّد حالات عدم التطابق بين HTML الخادم والعميل وأصلحها باستخدام suppressHydrationWarning. تتمرن على React Academy مع أكواد عملية تشغلها مباشرة في المتصفح، ومدرس ذكاء اصطناعي متاح 24/7 يجيب على أسئلتك أثناء عملك.
هل أحتاج إلى خبرة سابقة لأبدأ React Academy؟
لا تُشترط خبرة سابقة. React Academy على CoddyKit منظم للمبتدئين حتى المتقدمين، لذا يمكنك البدء من هنا أو من البداية والتقدم بسرعتك الخاصة. هذا هو الدرس 2 من أصل 4.
كم من الوقت يستغرق درس «أخطاء الإماهة: الأسباب والإصلاحات»؟
معظم دروس CoddyKit تستغرق حوالي 5–10 دقائق. كل منها موجز وتفاعلي، لذا تحرز تقدماً مستمراً وتستأنف من حيث توقفت عبر الويب والتطبيق.
هل يمكنني كتابة وتشغيل أكواد في درس React Academy هذا؟
نعم. كل درس في React Academy يتضمن محرر أكواد مدمج، لذا تكتب وتشغل أكواداً حقيقية مباشرة في متصفحك وتحصل على تعليقات فورية من الذكاء الاصطناعي — بدون إعداد محلي.
جميع الدروس في هذه الدورة
- كيف يعمل React SSR داخليًا
- أخطاء الإماهة: الأسباب والإصلاحات
- الإماهة الانتقائية وبث HTML
- نمط بنية الجزر