0Pricing
React Academy · درس

إنشاء مكوّن Modal باستخدام Portals

أنشئوا نافذة modal قابلة لإعادة الاستخدام تُصيّر داخل document.body عبر createPortal

إنشاء مكوّن Modal باستخدام Portals درس مجاني في React Academy على CoddyKit. هذا هو الدرس 2 من أصل 4. يمكنك قراءة الدرس كاملاً أدناه مجاناً — ثم تمرن عليه مباشرة في المتصفح باستخدام محرر أكواد مدمج ومدرس ذكاء اصطناعي متاح 24/7. هذا الدرس جزء من مسار التعلم في React Academy، وتقدمك يتزامن عبر الويب وتطبيق CoddyKit. تتضمن دورة React Academy 4 دروس في المجموع.

مرحبًا

ستبني في هذا الدرس مكوّن Modal قابلًا لإعادة الاستخدام، ويستخدم React.createPortal للعرض داخل document.body، مع دعم الإغلاق عند النقر على الخلفية أو الضغط على مفتاح Escape.

هيكل مكوّن Modal الأساسي

ابدأ بالهيكل الأساسي: مكوّن Modal يقبل الخصائص `isOpen` و`onClose` و`children`. وعندما تكون `isOpen` مساوية لـ false، لا تعرض شيئًا.
function Modal({ isOpen, onClose, children }) {
  if (!isOpen) return null;
  return createPortal(
    <div className="backdrop" onClick={onClose}>
      <div className="modal" onClick={e => e.stopPropagation()}>
        {children}
      </div>
    </div>,
    document.body
  );
}

الخلفية ومنع انتشار الحدث

تغطي div الخارجية المسماة `backdrop` الشاشة بأكملها. ويؤدي النقر عليها إلى استدعاء `onClose`. أما div الداخلية المسماة `modal` فتستدعي `e.stopPropagation()` حتى لا تتصاعد النقرات داخل النافذة إلى الخلفية وتغلقها عن طريق الخطأ.

الإغلاق باستخدام مفتاح Escape

أضف `useEffect` يستمع إلى حدث `keydown`. وعند الضغط على مفتاح Escape مع كون النافذة مفتوحة، استدعِ `onClose`. أزل المستمع عند التنظيف.
useEffect(() => {
  if (!isOpen) return;
  const handle = (e) => { if (e.key === 'Escape') onClose(); };
  document.addEventListener('keydown', handle);
  return () => document.removeEventListener('keydown', handle);
}, [isOpen, onClose]);

منع تمرير الصفحة

عند فتح نافذة منبثقة، ستحتاج عادةً إلى منع تمرير الصفحة الواقعة خلفها. أضف `overflow: hidden` إلى `document.body` وأزله منه داخل `useEffect`.
useEffect(() => {
  if (isOpen) {
    document.body.style.overflow = 'hidden';
  }
  return () => { document.body.style.overflow = ''; };
}, [isOpen]);

CSS الأساسي للنافذة المنبثقة

يجب أن تكون الخلفية طبقة تراكب ثابتة تغطي الشاشة بأكملها. ويجب توسيط صندوق النافذة. ويستخدم أسلوب CSS بسيط flexbox على الخلفية لتوسيط النافذة.
.backdrop {
  position: fixed; inset: 0;
  background: rgba(0,0,0,0.5);
  display: flex; align-items: center; justify-content: center;
  z-index: 1000;
}
.modal {
  background: white;
  border-radius: 8px;
  padding: 24px;
  min-width: 320px;
}

استخدام Modal

تحكّم في Modal باستخدام متغير حالة منطقي في المكوّن الأب. مرّر الخصائص `isOpen` و`onClose` إلى Modal. وضع أي محتوى باعتباره children.
function App() {
  const [open, setOpen] = useState(false);
  return (
    <>
      <button onClick={() => setOpen(true)}>Open Modal</button>
      <Modal isOpen={open} onClose={() => setOpen(false)}>
        <h2>Hello from the modal!</h2>
        <button onClick={() => setOpen(false)}>Close</button>
      </Modal>
    </>
  );
}

إضافة زر إغلاق من الداخل

وفّر دائمًا زر إغلاق واضحًا داخل النافذة للمستخدمين الذين لا يستطيعون استخدام لوحة المفاتيح أو لا يلاحظون الخلفية. مرّر `onClose` إلى المحتوى عبر children أو عبر خاصية.

التحريك باستخدام انتقالات CSS

لإضافة تأثير التلاشي، لا تُرجع null عند الإغلاق، بل اعرض Portal دائمًا وبدّل فئة CSS. استخدم انتقالًا لخاصيتي CSS `opacity` و`transform` على الخلفية.
// Toggle class based on isOpen
<div className={`backdrop ${isOpen ? 'visible' : 'hidden'}`}>

تركيب رأس Modal وتذييله

قسّم Modal إلى مكوّنات فرعية: `Modal.Header` و`Modal.Body` و`Modal.Footer`. استخدم نمط المكوّن المركّب حتى يتمكن المستخدمون من تركيب تخطيط Modal من دون معرفة أسماء الفئات.

تحقق سريع

لماذا نستدعي e.stopPropagation() في معالج onClick الخاص بـ div الداخلية للنافذة؟

مراجعة

لقد بنيت Modal باستخدام createPortal: يؤدي النقر على الخلفية إلى إغلاقها، ويغلقها مفتاح Escape، ويُمنع تمرير الصفحة أثناء فتحها، ويمنع stopPropagation النقرات داخل النافذة من إغلاقها.

التالي

الدرس التالي: **معالجة التركيز وحصر لوحة المفاتيح في النوافذ المنبثقة** — ستحافظ على التركيز داخل النافذة أثناء فتحها لاستيفاء متطلبات إمكانية الوصول.

الأسئلة الشائعة

هل درس «إنشاء مكوّن Modal باستخدام Portals» مجاني؟

نعم — نص درس «إنشاء مكوّن Modal باستخدام Portals» كامل متاح مجاناً هنا على الويب. لتمرينه بشكل تفاعلي (محرر أكواد مدمج ومدرس ذكاء اصطناعي متاح 24/7) وفتح باقي دورة React Academy، انتقل إلى CoddyKit PRO. تتضمن دورة React Academy 4 دروس في المجموع.

ماذا ستتعلم في «إنشاء مكوّن Modal باستخدام Portals»؟

أنشئوا نافذة modal قابلة لإعادة الاستخدام تُصيّر داخل document.body عبر createPortal تتمرن على React Academy مع أكواد عملية تشغلها مباشرة في المتصفح، ومدرس ذكاء اصطناعي متاح 24/7 يجيب على أسئلتك أثناء عملك.

هل أحتاج إلى خبرة سابقة لأبدأ React Academy؟

لا تُشترط خبرة سابقة. React Academy على CoddyKit منظم للمبتدئين حتى المتقدمين، لذا يمكنك البدء من هنا أو من البداية والتقدم بسرعتك الخاصة. هذا هو الدرس 2 من أصل 4.

كم من الوقت يستغرق درس «إنشاء مكوّن Modal باستخدام Portals»؟

معظم دروس CoddyKit تستغرق حوالي 5–10 دقائق. كل منها موجز وتفاعلي، لذا تحرز تقدماً مستمراً وتستأنف من حيث توقفت عبر الويب والتطبيق.

هل يمكنني كتابة وتشغيل أكواد في درس React Academy هذا؟

نعم. كل درس في React Academy يتضمن محرر أكواد مدمج، لذا تكتب وتشغل أكواداً حقيقية مباشرة في متصفحك وتحصل على تعليقات فورية من الذكاء الاصطناعي — بدون إعداد محلي.

جميع الدروس في هذه الدورة

  1. ما هي React Portals؟
  2. إنشاء مكوّن Modal باستخدام Portals
  3. التعامل مع التركيز ومصائد لوحة المفاتيح في النوافذ المنبثقة
  4. التلميحات والقوائم المنسدلة باستخدام Portals
← العودة إلى React Academy