انتقل إلى محتوى الدرس
الدرس 46
دورة ReactJS

العرض عبر البوابات createPortal وحدود عزل الأخطاءRendering with createPortal and Error Boundaries

تجاوز قيود القص والترتيب البصري للحاويات برسم النوافذ الحوارية عبر createPortal، وافهم صعود الأحداث عبر شجرة React، واعزل أعطال التصيير بأمان عبر Error Boundaries.
أقسام الدرس
6
الأمثلة
3
اللغة
العربية
تاريخ النشر
غير محدد
المشاهدات
0
محتوى الدرس
في هذا الدرس 6تصفّح المواضيع

في الوضع المعتاد، ترسم React عناصر HTML الخاصة بالمكون داخل عقدة أبيه المباشر في شجرة المتصفح. غير أن هذا التسلسل يسبب مشكلة بصرية شائعة عندما تحاول بطاقة مقيدة بخاصية overflow: hidden أو transform فتح نافذة حوارية شاملة أو قائمة منبثقة، إذ يقتطع المتصفح أطراف النافذة عند حدود البطاقة الضيقة!

تحل الدالة createPortal(children, domNode) المستوردة من حزمة react-dom هذه المعضلة بنقل الرسم الفيزيائي للعناصر إلى حاوية عليا مثل document.body مع بقاء المكون في موضعه المنطقي الكامل داخل شجرة React:

HTML
import { createPortal } from 'react-dom';

function FloatingNotice({ open, onClose }) {
  if (!open) return null;
  return createPortal(
    <div role="status">
      Saved! <button onClick={onClose}>OK</button>
    </div>,
    document.body
  );
}

عند بناء نافذة حوارية قياسية باستخدام createPortal()، اجمع بين النقل البصري ومعايير الوصول الشامل ودعم الثيمات: أضف سمات role="dialog" وaria-modal="true" وaria-labelledby، واربط زر الهروب Escape عبر تأثير useEffect() مع دالة تنظيف، واستخدم متغيرات الألوان الدلالية لدعم الوضعين الفاتح والداكن:

HTML
useEffect(() => {
  if (!open) return;
  const onKey = (e) => e.key === 'Escape' && onClose();
  window.addEventListener('keydown', onKey);
  return () => {
    window.removeEventListener('keydown', onKey);
  };
}, [open, onClose]);

هناك تفصيل معماري بالغ الأهمية يفاجئ حتى المطورين المتمرسين: تصعد الأحداث التفاعلية داخل البوابة عبر شجرة مكونات React المنطقية، وليس عبر شجرة HTML الفيزيائية فقط!

فإذا وضعت بوابة نافذة حوارية داخل عنصر أب يملك معالج onClick، فإن النقر على زر الإغلاق داخل النافذة المرسومة في document.body سيصعد عبر شجرة React ويشغّل معالج النقر في الأب ما لم توقف الانتشار عبر e.stopPropagation() أو تضع مكون النافذة خارج العنصر القابل للنقر.

مخطط ثلاثي يوضح إخراج النوافذ عبر createPortal واستمرار صعود الأحداث في شجرة React وعزل أعطال التصيير بحدود الأخطاء

كما تحمي البوابات حدود التخطيط البصري، تحمي حدود عزل الأخطاء (Error Boundaries) استقرار التطبيق وقت التشغيل. فإذا واجهت أداة فرعية بيانات تالفة غير متوقعة أثناء التصيير—مثل قراءة خاصية من كائن قيمته null—يُرمى استثناء برمجي فوري.

في السلوك الافتراضي غير المحمي، تزيل React شجرة التطبيق بأكملها عند وقوع خطأ تصيير غير معالج، فتظهر شاشة فارغة بدلاً من بقاء واجهة معطوبة قد تضلل المستخدم.

يحيط غلاف Error Boundary بالأقسام المستقلة في شاشتك—كمخطط الأسهم أو قسم التعليقات أو المكونات الكسولة—ليعرض بطاقة بديلة آمنة مع زر إعادة المحاولة عند تعطل ذلك القسم وحده، بينما تواصل بقية الصفحة عملها دون انقطاع.

انتبه لحقيقة معمارية خاصة في React الحديثة: تُعد حدود الأخطاء الاستثناء المعماري الوحيد الذي لا يزال يعتمد داخلياً على الدالة الثابتة getDerivedStateFromError ودالة التسجيل componentDidCatch لعدم توفر خطاف مكافئ لها بعد. وفي المشاريع العملية تكتب هذا الغلاف الصغير مرة واحدة فقط في ملف مساعد مشترك وتبقى جميع مكونات تطبيقك دوالَّ حديثة بنسبة 100%:

HTML
class ErrorBoundary extends Component {
  state = { hasError: false };
  static getDerivedStateFromError() {
    return { hasError: true };
  }
  render() {
    const { hasError } = this.state;
    return hasError
      ? this.props.fallback
      : this.props.children;
  }
}

من الضروري التمييز بدقة بين ما تصطاده حدود الأخطاء وما لا يدخل في نطاقها: تلتقط ErrorBoundary الأخطاء المرمية أثناء طور التصيير وبما يشمل فشل تحميل حزم React.lazy، لكنها لا تلتقط أخطاء دوال الأحداث مثل onClick ولا أخطاء fetch غير المتزامنة؛ فتلك تُعالج ببنية try / catch وحالة الخطأ الاعتيادية كما تعلمت في الوحدة الثامنة. يوضح الجدول التالي آلية التعامل مع كل نوع:

مصدر الخطأ البرمجيهل تلتقطه ErrorBoundary؟الأسلوب الهندسي الصحيح للمعالجة
قراءة خاصية فارغة أثناء تصيير JSXنعم — تلتقطه وتعزله فوراًتغليف الأقسام المستقلة بحد ErrorBoundary
فشل تحميل حزمة React.lazy الشبكيةنعم — يلتقطه الحد المحيط بـ Suspenseعرض بطاقة إعادة المحاولة داخل واجهة البديل
خطأ داخل معالج حدث مثل onClickلا — يقع خارج طور التصييراستخدام try/catch وتحديث حالة الخطأ في المكون
رفض طلب fetch أو مؤقت غير متزامنلا — يعمل في نطاق غير متزامنمعالجة رفض الوعد وتخزين رسالة الخطأ بالحالة
خلاصة المعرفة ومحطة الانتقال

ملخص الدرس

حصاد الدرس

مراجعة مركّزة لأهم المفاهيم والقواعد الهندسية التي أتقنتها في هذا الدرس قبل التطبيق العملي

ماذا تعلّمت في هذا الدرس؟

أتقنت في هذا الدرس إخراج النوافذ الحوارية السليمة عبر createPortal لتجاوز قيود القص مع فهم صعود الأحداث في شجرة React، وعزل أعطال التصيير بحدود Error Boundaries لحماية استقرار التطبيق. الخطوة التالية: انتقل الآن إلى الدرس رقم 47 «مفهوم التوجيه في تطبيقات الصفحة الواحدة وإعداد React Router» لمواصلة البناء التراكمي المتدرج في مسار React الحديث.

مشاركة

هل كان هذا الدرس مفيدًا؟

جارٍ تحميل الآراء…

ابنِ لغتك البرمجية

المصطلحات4

راجع المعنى، اشرحه لنفسك، ثم علّم البطاقة كمفهومة.

0 / 4 مفهومةأول بطاقة، أول خطوة
01 Portal البوابة البرمجية Portal
آلية عبر دالة createPortal تتيح رسم عناصر المكون في عقدة DOM خارجية مثل document.body مع بقائه منطقياً داخل شجرة React.
للمراجعة
02 Stacking Context سياق الترتيب الطبقي
قواعد ترتيب الطبقات في المتصفح الناتجة عن خصائص مثل overflow وz-index والتي تتجاوزها البوابات بنجاح.
للمراجعة
03 Error Boundary حد عزل الأخطاء
مكون غلاف وقائي في React يلتقط أخطاء التصيير المرمية في شجرته الفرعية ويعرض واجهة بديلة آمنة دون انهيار الصفحة.
للمراجعة
04 Fallback UI واجهة الاستعادة البديلة
بطاقة تنبيه آمنة قابلة لإعادة المحاولة تحل محل القسم المتعطل لحماية تجربة المستخدم.
للمراجعة

اقرأ البطاقات بحرية. سجّل الدخول لحفظ تقدم مراجعتك.

حروف قليلة. معنى كامل.

الاختصارات4

راجع المعنى، اشرحه لنفسك، ثم علّم البطاقة كمفهومة.

0 / 4 مفهومةأول بطاقة، أول خطوة
01 ARIA ARIA
Accessible Rich Internet Applications
سمات إتاحة قياسية مثل role="dialog" وaria-modal="true" ضرورية لدعم قارئات الشاشة في النوافذ الحوارية.
للمراجعة
02 DOM DOM
Document Object Model
شجرة المستند الفيزيائية التي تلحق بها البوابة عناصر النافذة مباشرة داخل document.body.
للمراجعة
03 CSS CSS
Cascading Style Sheets
طبقة التنسيق التي قد تقتطع القوائم المنبثقة غير المخرجة عبر بوابة عند استخدام overflow: hidden.
للمراجعة
04 UX UX
User Experience
جودة واستمرارية تجربة المستخدم عند عزل عطل أداة فرعية دون فقدان بيانات بقية الشاشة.
للمراجعة

اقرأ البطاقات بحرية. سجّل الدخول لحفظ تقدم مراجعتك.

من الفهم للتطبيق

مهامك قبل الاختبار

خطوة صغيرة كل مرة. وإنجاز تقدر ترجع له.

0/2مهام منجزة
  1. شغّل مثال ProjectSettings في محرر التجريب وافتح نافذة الأرشفة وجرّب إغلاقها بمفتاح Escape تارة وبالنقر على الخلفية الداكنة تارة أخرى.

  2. اكتب نصاً خاصاً في حقل الملاحظات المجاور داخل مثال ResilientDashboard ثم اضغط محاكاة العطل وتأكد من بقاء نصك سليماً ثم أعد تفعيل الأداة.

تأشير المهمة إقرار منك بإتمامها، وليس تصحيحًا آليًا للكود. يُحفظ تقدمك في حسابك.

مساحة التحدي

اختبر فهمك.
ووصلها للإتقان.

كل سؤال خطوة لقدّام. اختار، اكتب كود، وشوف نتيجتك فورًا.

10أسئلة 2أنواع تحديات 100%هدف الإتقان
تصحيح تلقائي. فرص بلا حدود.

أكمل المهام، واجمع كل الإجابات الصحيحة. أقل من 100%؟ راجع وأعد المحاولة.

الأسئلة متاحة للاطلاع. سجّل الدخول للتفاعل وحفظ تقدمك.

لمحة عن التحدي10 أسئلة تنتظرك
01

من أي حزمة برمجية تُستورد الدالة createPortal في تطبيقات ويب React؟

تُستورد دالة createPortal مباشرة من الحزمة الخاصة بالمتصفح react-dom.

02

ما المشكلة البصرية الأساسية التي تحلها دالة createPortal عند رسم النوافذ والقوائم العائمة؟

تُخرج العنصر من قيود القص البصري overflow: hidden وسياقات الترتيب الضيقة للحاويات الأب.

03

يظل المكون المرسوم عبر createPortal في document.body قادراً على قراءة قيم السياق Context من آبائه في شجرة React.

صواب؛ تغير البوابة مكان عقد HTML الفيزيائي فقط بينما يبقى المكون متصلاً بالكامل بشجرة السياق في React.

04

كيف تصعد أحداث النقر المتولدة داخل نافذة مرسومة عبر createPortal؟

تصعد الأحداث عبر شجرة مكونات React المنطقية لتصل إلى آباء المكون في JSX.

05

ما التفاعل اللوحي وسمات الإتاحة الضرورية عند بناء نافذة حوارية قياسية؟

توفير سمات role="dialog" وaria-modal="true" وربط العنوان ودعم الإغلاق بمفتاح Escape.

06

ماذا تفعل React افتراضياً إذا رمى مكون فرعي خطأ غير معالج أثناء التصيير دون وجود حد عزل أخطاء؟

تزيل React شجرة مكونات التطبيق بأكملها لتجنب بقاء واجهة معطوبة أو مضللة أمام المستخدم.

07

يحافظ تغليف مخطط بياني بحد Error Boundary على بقاء النماذج والملاحظات المجاورة شغالة بأمان حتى لو تعطل المخطط أثناء الرسم.

صواب؛ يُستبدل القسم المتعطل وحده بواجهة الاستعادة البديلة بينما تستمر بقية الشاشة بالعمل.

08

تلتقط حدود Error Boundaries تلقائياً الأخطاء التي تحدث داخل دوال النقر onClick على الأزرار.

خطأ؛ تعمل معالجات الأحداث خارج طور التصيير، لذا تُعالج أخطاؤها عبر try/catch وتحديث حالة الخطأ.

09

كيف تعالج فشل تحميل حزمة مكون كسول React.lazy عند انقطاع اتصال الشبكة لدى المستخدم؟

بوضع غلاف Error Boundary يحيط بحد الانتظار Suspense لالتقاط الفشل وعرض بطاقة إعادة المحاولة.

10

لماذا يكتفي مشروع React الحديث بملف غلاف ErrorBoundary واحد فقط بينما تُبنى سائر المكونات كدوال؟

لأن خطافات React لا تتضمن بعد بديلاً لدالة getDerivedStateFromError، ويكفي غلاف واحد مشترك لحماية جميع المكونات الدالية.