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

متى لا تحتاج إلى useEffect والبدائل الهندسية الأنظفWhen You Do Not Need useEffect

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

صُمم خطاف useEffect كمنفذ لمزامنة الأنظمة الخارجية حصراً؛ فإذا لم يكن هناك نظام خارجي حقيقي فإن إقحام التأثير يجعل الكود أبطأ وأصعب في التتبع وعرضة للوميض البصري. إذ يجبر التأثير الزائد مكتبة React على التصيير أولاً بقيمة قديمة، ورسمها على الشاشة، ثم تشغيل التأثير وإطلاق دورة تصيير ثانية مهدرة فوراً.

لذلك يُعد حذف التأثيرات غير الضرورية من أرفع مهارات تحسين جودة وأداء تطبيقات React الحديثة.

متى أمكن حساب قيمة بالكامل اعتماداً على props أو state الموجودة بالفعل — مثل دمج الاسم الكامل، أو تصفية قائمة الدورات، أو جمع إجمالي الساعات — فلا تضعها في حالة مستقلة ولا تحدثها عبر useEffect أبداً.

احسبها مباشرة كمتغير const عادي في جسم دالة المكون لتكون محدثة ودقيقة بنسبة 100% منذ دورة التصيير الأولى.

HTML
const [query, setQuery] = useState('');
const visible = COURSES.filter((c) =>
  c.title.toLowerCase().includes(query.toLowerCase())
);
const totalHours = visible.reduce(
  (sum, c) => sum + c.hours,
  0
);

للحسم الدقيق بين وضع الكود في معالج الحدث أو داخل التأثير، اسأل نفسك لماذا يجب أن يعمل هذا السطر الآن:

  • لأن المستخدم ضغط زراً محدداً أو أرسل نموذجاً: ضع الكود داخل onClick أو onSubmit مباشرة؛ وإذا اشترك زرّان في نفس الخطوات فاستخرج دالة مساعدة عادية واستدعها منهما معاً بدلاً من رفع راية حالة مؤقتة لتشغيل تأثير!
  • لأن المكون ظهر وعُرض أمام المستخدم على الشاشة: هنا نستخدم useEffect.
مقارنة معمارية بين النمط الخاطئ لمزامنة الحالة بتأثير يسبب تصييرين وبين النمط الصحيح لحساب القيمة مباشرة أثناء التصيير في دورة واحدة
HTML
function completeEnrollment(mode) {
  setReceipt('Enrolled via ' + mode + ' for ' + plan);
}
// Called directly from onClick — no Effect flag needed!

من أكثر الأخطاء شيوعاً كتابة useEffect(() => { setComment(""); }, [userId]) داخل مكون فرعي لتفريغ المسودة عند الانتقال لطالب أو ملف شخصي آخر؛ إذ يعرض ذلك مسودة المستخدم السابق للحظة فوق ملف المستخدم الجديد قبل مسحها!

الحل الهندسي الأنظف هو تمرير المعرّف لخاصية المفتاح <CommentDraft key={userId} user={activeUser} />؛ فتعاملها React كنسخة مكون جديدة وتصفّر حالتها الداخلية تلقائياً في تصيير واحد.

HTML
function Workspace() {
  const [studentId, setStudentId] = useState('s1');
  return (
    <MentorNoteBox
      key={studentId}
      studentId={studentId}
    />
  );
}

تجنب كذلك «سلاسل التأثيرات المتعاقبة» حين يحدّث المكون الفرعي حالته في حدث النقر ثم يعتمد على useEffect منفصل لإبلاغ المكون الأب عبر onChange(nextValue)؛ فذلك يبعثر التحديث الواحد على عدة تصييرات متتالية.

البديل السليم هو استدعاء دالة الأب وتحديث الحالة معاً داخل نفس دالة الحدث، أو رفع الحالة بالكامل للأب ليصبح المكون الفرعي محكوماً وبسيطاً.

اعتمد جدول القرار الهندسي التالي بوصلةً عملية لتحديد الموضع الصحيح لكل منطق برمجي داخل تطبيقات React:

الهدف البرمجيالنمط الخاطئ بـ useEffectالحل الهندسي الأنظف في React
تصفية القوائم أو حساب المجاميعنسخ النتيجة في حالة ثانية داخل تأثيرحساب القيمة مباشرة بمتغير const أثناء العرض
تصفير حالة مكون فرعي عند تغير المعرّفتصفير الحقول يدوياً داخل useEffectتمرير خاصية key={id} للمكون الفرعي مباشرة
إرسال طلب أو إبلاغ الأب عند النقررفع راية حالة لتشغيل تأثير لاحقتنفيذ الإجراء مباشرة داخل دالة الحدث onClick
مزامنة عنوان الصفحة أو مستمع النافذةالتعديل المباشر أثناء دالة التصييراستخدام useEffect مع اعتماديات دقيقة وتنظيف
خلاصة المعرفة ومحطة الانتقال

ملخص الدرس

حصاد الدرس

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

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

تعلّمت في هذا الدرس رصد وإزالة استدعاءات useEffect الزائدة عبر اشتقاق البيانات مباشرة أثناء التصيير، ومعالجة إجراءات المستخدم في دوال الأحداث، وتصفير حالة المكونات الفرعية فورياً بخاصية key، ودمج إبلاغ المكون الأب بكفاءة. الخطوة التالية: انتقل الآن إلى الدرس رقم 37 «جلب البيانات من واجهات API داخل مكونات React» لمواصلة البناء التراكمي المتدرج في مسار React الحديث.

مشاركة

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

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

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

المصطلحات4

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

0 / 4 مفهومةأول بطاقة، أول خطوة
01 Derived Value القيمة المشتقة
كل قيمة تُحسب مباشرة أثناء التصيير من الخصائص والحالة الحالية دون تخزينها في حالة مكررة.
للمراجعة
02 Redundant Effect التأثير الزائد
استخدام غير ضروري لخطاف useEffect لتحويل بيانات داخلية أو معالجة نقرة مما يسبب تصييراً مضاعفاً.
للمراجعة
03 Key Reset Pattern نمط التصفير بالمفتاح
تمرير معرّف متغير لخاصية key لإزالة النسخة السابقة وتركيب نسخة جديدة بحالة ابتدائية نظيفة.
للمراجعة
04 Effect Chain سلسلة التأثيرات المتعاقبة
نمط سيئ يشغّل فيه كل تأثير تأثيراً آخر عبر تحديثات حالة متلاحقة بدلاً من الدمج في حدث واحد.
للمراجعة

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

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

الاختصارات4

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

0 / 4 مفهومةأول بطاقة، أول خطوة
01 UI UI
User Interface
واجهة المستخدم التي تبقى خالية من الوميض بفضل حساب البيانات المشتقة في دورة رسم واحدة.
للمراجعة
02 ID ID
Identifier
معرّف السجل الفريد الذي نمرره لخاصية key لتصفير حالة المكون الفرعي عند التبديل.
للمراجعة
03 JSX JSX
JavaScript XML
بنية العناصر في React حيث تتحكم سمة key في هوية المكون واستمرارية حالته.
للمراجعة
04 DOM DOM
Document Object Model
شجرة المتصفح التي نوفر عليها التحديثات المزدوجة بحذف التأثيرات غير الضرورية.
للمراجعة

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

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

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

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

0/2مهام منجزة
  1. افتح مثال DerivedCatalog وأضف مربع اختيار لتصفية الوحدات ذات 5 ساعات فأكثر مباشرة أثناء دالة التصيير.

  2. اكتب ملاحظة للطالبة Noor في المثال ثم انتقل إلى Tariq وتأكد من تفريغ الحقل لحظياً بفضل خاصية المفتاح.

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

مساحة التحدي

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

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

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

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

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

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

عند وجود firstName وlastName في الحالة، ما الطريقة الهندسية الأنظف لعرض الاسم الكامل fullName؟

حساب الاسم الكامل مباشرة في متغير const داخل جسم دالة التصيير دون حالة إضافية أو تأثير.

02

تؤدي مزامنة القيم المشتقة عبر useEffect وحالة إضافية إلى دورة تصيير زائدة بعد رسم بيانات متأخرة.

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

03

كيف نصفر جميع حالات المكون الفرعي <ProfileEditor /> تلقائياً فور تغير معرّف المستخدم selectedUser.id؟

نمرر خاصية key={selectedUser.id} لتستبدل React النسخة القديمة بأخرى جديدة ذات حالة ابتدائية نظيفة.

04

أين نضع كود تأكيد التسجيل وإظهار الإشعار المرتبط حصراً بنقر المستخدم على زر التسجيل؟

الإجراءات الناتجة عن فعل محدد من المستخدم مكانها الطبيعي داخل معالج الحدث onClick أو onSubmit.

05

تعمل خاصية key داخل قوائم map() فقط ولا تأثير لها عند وضعها على مكون فرعي منفرد.

خطأ؛ فتغيير قيمة key على أي مكون منفرد يأمر React باستبدال نسخته وتصفير حالته فوراً.

06

عندما يحتاج مكون تبديل إلى تحديث حالته وإبلاغ المكون الأب عبر onChange(next)، كيف نتفادى التأثير الزائد؟

نستدعي تحديث الحالة ودالة الأب معاً داخل نفس معالج الحدث ليدمجهما React في تصيير واحد.

07

إذا اشترك زرّان في نفس خطوات التحقق والتسجيل، كيف نمنع تكرار الكود دون اللجوء إلى useEffect؟

نستخرج دالة مساعدة عادية داخل المكون ونستدعيها مباشرة من كلا معالجي النقر.

08

إذا لم يكن هناك نظام خارجي وكنت تحسب بيانات الواجهة من الخصائص والحالة الحالية فقط، فلا حاجة غالباً إلى useEffect.

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

09

أي حالة من الحالات الأربع التالية تتطلب فعلاً استخدام خطاف useEffect؟

ربط وإزالة مستمع حدث resize على كائن النافذة العام يمثل مزامنة حقيقية مع نظام خارجي.

10

تدمج مكتبة React 18 تلقائياً تحديثات الحالة المتعددة داخل نفس معالج النقر في دورة تصيير واحدة.

صواب؛ تحافظ ميزة الدمج التلقائي على سرعة واتساق الواجهة دون تصييرات متفرقة.