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

دوال تنظيف التأثيرات ودورة حياة useEffectEffect Cleanup Functions and Reactive Lifecycle

اكتب دوال التنظيف داخل useEffect لإلغاء المؤقتات ومستمعي أحداث النافذة ومنع تسرب الذاكرة، وافهم دورة المزامنة وفحص المتانة في الوضع الصارم StrictMode.
أقسام الدرس
6
الأمثلة
3
اللغة
العربية
تاريخ النشر
غير محدد
المشاهدات
0
محتوى الدرس
في هذا الدرس 6تصفّح المواضيع

كثير من عمليات المزامنة الخارجية مستمرة بطبيعتها وليست خطوة لحظية تنتهي فوراً؛ فتشغيل مؤقت دوري عبر setInterval أو تسجيل مستمع على النافذة عبر window.addEventListener أو فتح اشتراك بقناة بيانات يظل نشطاً في ذاكرة المتصفح إلى أن نوقفه صراحةً.

إذا أخفى المستخدم المكون أو انتقل لشاشة أخرى دون إلغاء ما بدأه التأثير، ستتراكم المؤقتات اليتيمة وتتضاعف المستمعات مع كل زيارة مما يسبب تسرب الذاكرة وتضارب تحديثات الواجهة.

لإيقاف أي تأثير مستمر بنظافة، أعِد دالة تنظيف (Cleanup Function) من نهاية دالة useEffect بالشكل return () => { ... }. تستدعي React دالة التنظيف هذه تلقائياً في موضعين دقيقين:

  1. قبل إعادة تشغيل التأثير: عند تغير إحدى الاعتماديات تنفذ React تنظيف الدورة السابقة بقيمها القديمة أولاً قبل بدء الإعداد الجديد.
  2. عند إزالة المكون (Unmount): مرة أخيرة فور اختفاء المكون من شجرة الواجهة.
HTML
useEffect(() => {
  onLog('+ Connected to #' + room);
  return () => {
    onLog('- Disconnected from #' + room);
  };
}, [room]);

كلما أنشأ التأثير مؤقتاً عبر setInterval() أو setTimeout()، احفظ معرّف المؤقت في ثابت محلي داخل دالة التأثير ثم ألغِه فوراً في دالة التنظيف باستدعاء clearInterval(id) أو clearTimeout(id).

ادمج ذلك مع دالة التحديث المعتمدة على القيمة السابقة setSeconds((s) => s + 1) ليعمل العداد بسلاسة دون الحاجة لإعادة إنشاء المؤقت في كل ثانية.

مخطط يوضح دورة حياة التنظيف في useEffect: تشغيل الإعداد عند التركيب ثم تغير الاعتمادية ثم تنظيف الأثر السابق ثم تشغيل الإعداد الجديد
HTML
useEffect(() => {
  if (!active) return;
  const id = setInterval(() => {
    setSeconds((s) => s + 1);
  }, 1000);
  return () => clearInterval(id);
}, [active]);

ترتبط خصائص مثل onClick بعناصر المكون نفسه، أما الأحداث العامة على مستوى المتصفح — كتغير عرض النافذة resize أو حالة الاتصال بالشبكة أو اختصارات لوحة المفاتيح العامة مثل مفتاح Escape — فتُسجل على كائن window أو document.

عرّف دالة معالجة مسماة داخل التأثير، ومررها إلى window.addEventListener، ثم مرر نفس مرجع الدالة بالضبط إلى window.removeEventListener داخل دالة التنظيف.

HTML
useEffect(() => {
  function onKey(e) {
    setLastKey(e.key);
  }
  window.addEventListener('keydown', onKey);
  return () => {
    window.removeEventListener('keydown', onKey);
  };
}, []);

في معمارية React الدالية الحديثة، تخلَّ عن التفكير بطريقة مراحل الأصناف المتفرقة القديمة، وفكّر في كل تأثير كزوج متناظر مستقل من بدء المزامنة وإيقاف المزامنة. اجعل كل استدعاء useEffect مسؤولاً عن مهمة مترابطة واحدة؛ فإذا أردت مزامنة عنوان الصفحة ومراقبة عرض النافذة معاً، افصلهما في خطافين مستقلين واضحين.

في طور التطوير، يتعمد غلاف <StrictMode> تشغيل دورة اختبار إضافية بالترتيب إعداد ← تنظيف ← إعداد فور تركيب المكون. فإذا لاحظت تضاعف سرعة العداد في وضع التطوير، لا تحذف الوضع الصارم، بل أصلح دالة التنظيف المفقودة التي كشفها لك مبكراً قبل وصول الكود للإنتاج! يوضح الجدول الآتي أزواج التنظيف القياسية:

عملية الإعداد في التأثيردالة التنظيف المتناظرةنتيجة إهمال دالة التنظيف
تشغيل مؤقت دوري setIntervalإلغاء المؤقت عبر clearInterval(id)تراكم مؤقتات مزدوجة وتضاعف سرعة العداد
جدولة تأخير زمني setTimeoutإلغاء الجدولة عبر clearTimeout(id)تنفيذ متأخر غير مرغوب بعد مغادرة الشاشة
تسجيل مستمع window.addEventListenerإزالة المستمع عبر removeEventListenerتسرب ذاكرة وتكرار تنفيذ الحدث عشرات المرات
فتح اتصال أو أداة خارجية connectإغلاق الاتصال عبر disconnect أو closeبقاء قنوات يتيمة مفتوحة وتداخل بيانات الغرف
خلاصة المعرفة ومحطة الانتقال

ملخص الدرس

حصاد الدرس

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

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

أتقنت في هذا الدرس كتابة دوال التنظيف في useEffect، وتتبعت ترتيب الإعداد والهدم عند تغير الاعتماديات وإزالة المكون، وألغيت المؤقتات ومستمعي النافذة بأمان مع استيعاب عقلية بدء وإيقاف المزامنة وفحص StrictMode. الخطوة التالية: انتقل الآن إلى الدرس رقم 36 «متى لا تحتاج إلى useEffect والبدائل الهندسية الأنظف» لمواصلة البناء التراكمي المتدرج في مسار React الحديث.

مشاركة

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

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

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

المصطلحات4

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

0 / 4 مفهومةأول بطاقة، أول خطوة
01 Cleanup Function دالة التنظيف
دالة تُعاد من داخل useEffect وتتولى إلغاء المؤقتات والمستمعات والاشتراكات التي أنشأها الإعداد.
للمراجعة
02 Memory Leak تسرب الذاكرة
بقاء مؤقتات أو مستمعات نشطة تستهلك الذاكرة والمعالج بعد إزالة المكون من الواجهة.
للمراجعة
03 Synchronization Pair زوج المزامنة المتناظر
تصميم كل إجراء فتح أو اشتراك في التأثير مقروناً بإجراء الإغلاق المعاكس له تماماً.
للمراجعة
04 Unmount إزالة المكون
لحظة حذف نسخة المكون من شجرة العرض واستدعاء دوال تنظيف تأثيراته للمرة الأخيرة.
للمراجعة

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

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

الاختصارات4

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

0 / 4 مفهومةأول بطاقة، أول خطوة
01 CPU CPU
Central Processing Unit
موارد المعالج التي تُستنزف عند ترك مؤقتات خلفية منسية تعمل بلا توقف.
للمراجعة
02 RAM RAM
Random Access Memory
ذاكرة المتصفح التي تبقى محجوزة بسبب عدم إزالة مستمعات الأحداث العامة.
للمراجعة
03 DOM DOM
Document Object Model
أهداف النافذة والمستند العامة التي نربط بها مستمعات لوحة المفاتيح وتغير الحجم.
للمراجعة
04 UI UI
User Interface
عروض المكونات التفاعلية التي تُركب وتُزال ديناميكياً أثناء تنقل المستخدم.
للمراجعة

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

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

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

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

0/2مهام منجزة
  1. افتح مثال LifecycleInspector وبدّل من غرفة general إلى hooks وتحقق من ظهور سطر التنظيف قبل سطر الاتصال الجديد.

  2. عدّل دالة handleKeyDown بحيث يؤدي الضغط على مفتاح Escape إلى عرض رسالة مسح مخصصة مع الحفاظ على التنظيف السليم.

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

مساحة التحدي

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

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

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

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

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

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

كيف نعرّف آلية التنظيف داخل خطاف useEffect في React؟

نعيد دالة تنظيف سهمية أو مسماة من نهاية دالة الإعداد داخل useEffect.

02

في أي الأوقات تستدعي مكتبة React دالة التنظيف المعادة من التأثير؟

تستدعيها React قبل إعادة تشغيل التأثير عند تغير الاعتماديات، وكذلك عند إزالة المكون من الشجرة.

03

يتعمد غلاف StrictMode في طور التطوير تشغيل دورة إعداد ثم تنظيف ثم إعداد إضافية لكشف أخطاء التنظيف مبكراً.

صواب؛ فإذا كانت دالة التنظيف متناظرة وسليمة فسيعمل المكون بكفاءة مطابقة للإنتاج تماماً.

04

لماذا يفشل تمرير دالة سهمية مجهولة جديدة إلى window.removeEventListener في إزالة المستمع السابق؟

لأن كل دالة سهمية مكتوبة مباشرة تنشئ مرجعاً جديداً مختلفاً في الذاكرة فلا يتطابق مع الدالة المسجلة.

05

ما السطر المتناظر الواجب إرجاعه لتنظيف المؤقت const id = setInterval(tick, 1000)؟

إرجاع دالة تنظيف تستدعي clearInterval(id) لإلغاء المؤقت بدقة.

06

عند تغير roomId من "general" إلى "hooks"، تقرأ دالة التنظيف الخاصة بالدورة السابقة القيمة القديمة "general" وتغلقها بدقة.

صواب؛ لأن دالة التنظيف تحتفظ بلقطة القيم التي أُنشئت معها في دورتها الخاصة.

07

إذا احتاج مكون إلى مزامنة عنوان الصفحة مع [unread] والاتصال بغرفة محادثة مع [roomId]، فما الهيكلة الأفضل؟

فصلهما في استدعاءين مستقلين لخطاف useEffect حتى لا ينقطع اتصال الغرفة عند تغير عداد الرسائل.

08

التأثير البسيط الذي يحدّث نص document.title فقط دون فتح مؤقت أو مستمع أو اشتراك لا يلزمه إرجاع دالة تنظيف.

صواب؛ نحتاج دالة التنظيف عندما يفتح التأثير عملية مستمرة أو مستمعاً أو اتصالاً يجب إيقافه.

09

أثناء التطوير داخل <StrictMode> لاحظت أن العداد يزيد بمقدار 2 في كل ثانية؛ ما الحل الهندسي الصحيح؟

إضافة دالة التنظيف clearInterval(timerId) لإلغاء المؤقت الأول بدلاً من إخفاء المشكلة بحذف StrictMode.

10

استخدام التحديث الدالي setSeconds(prev => prev + 1) داخل المؤقت يغني عن وضع متغير seconds في مصفوفة الاعتماديات.

صواب؛ إذ تستلم دالة التحديث أحدث قيمة تلقائياً دون الحاجة لهدم المؤقت وإعادة إنشائه كل ثانية.