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

تصميم هيكل الحالة وحساب القيم المشتقةChoosing State Structure and Derived Values

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

تنص القاعدة الثانية على منع الحالات المتناقضة. تخيل مكون طلب شراء يعرّف متغيرين منطقيين منفصلين isSubmitting وisSubmitted؛ فلو نسي المطور تصفير الأول في أحد المسارات فسيصبح الاثنان true في اللحظة نفسها، وهي حالة مستحيلة تعرض مؤشر الانتظار ورسالة النجاح معاً!

استبدل الرايات المتضاربة بمتغير حالة نصي واحد status يمثل المرحلة بدقة مثل 'typing' أو 'submitting' أو 'success'، واشتق الثوابت المنطقية المقروءة أثناء التصيير.

HTML
function PublishPanel() {
  const [status, setStatus] = useState('draft');
  const isPublishing = status === 'publishing';
  const isPublished = status === 'published';
  return (
    <button disabled={isPublishing}
      onClick={() => setStatus('published')}>
      {isPublished ? 'Live!' : 'Publish Lesson'}
    </button>
  );
}

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

متى أمكن استنتاج قيمة حسابياً من الحالة أو الخصائص الموجودة، احسبها كمتغير const عادي مباشرة أثناء التصيير دون استدعاء useState() جديد.

مقارنة مزدوجة بين البنية المكررة المتناقضة بالرايات المتعددة وبين البنية القياسية المختصرة وحساب القيم المشتقة أثناء التصيير
HTML
function CartSummary({ items }) {
  const count = items.length;
  const total = items.reduce((s, i) => s + i.price, 0);
  const hasBonus = total >= 50;
  return <p>{count} courses — Total: ${total}</p>;
}

تنص القاعدة الرابعة على منع تكرار الكائنات داخل الحالة. فلو كنت تبني قائمة دروس قابلة للتعديل وخزّنت المصفوفة lessons وبجانبها نسخة كاملة من الكائن المختار selectedLesson، فإن تعديل عنوان الدرس داخل المصفوفة سيترك الكائن المنسوخ حاملاً للعنوان القديم المتقادم!

الحل القياسي هو تخزين المعرّف فقط selectedId، ثم استخراج الكائن الحي في كل تصيير عبر lessons.find((l) => l.id === selectedId).

HTML
const [items, setItems] = useState(INITIAL_MODS);
const [selectedId, setSelectedId] = useState('m1');
const active = items.find((m) => m.id === selectedId);

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

يفضّل المهندسون تسطيح هيكل البيانات (Normalized State) عبر مصفوفة مسطحة يحمل كل عنصر فيها معرّف الأب parentId أو قاموس مفهرس بالمعرّفات، بحيث يتم أي تعديل بنسخ سطحي واحد نظيف.

وأخيراً، تجنب نسخ الخصائص القادمة من الأب داخل متغير حالة إلا إذا كنت تقصد عمداً تجاهل كل تحديث مستقبلي! فكتابة const [bg, setBg] = useState(color) تقرأ القيمة الابتدائية عند أول تصيير فقط، وإذا غيّر الأب خاصية color لاحقاً فستظل الحالة عالقة على اللون القديم.

استخدم الخاصية مباشرة في العرض، وإذا أردت قيمة ابتدائية لمرة واحدة فسمِّ الخاصية بوضوح initialColor. يجمع الجدول التالي القواعد الهندسية لتصميم الحالة:

الخطأ المعماري في الحالةالمشكلة الناتجة في الواجهةالتصميم القياسي النظيف في React
رايات منطقية متعددة متضاربةظهور حالتين متناقضتين في اللحظة نفسهامتغير status نصي واحد واضح المراحل
تخزين المجاميع والفلاتر بالحالةاختلاف الأرقام عند إضافة أو حذف عنصرحساب القيم المشتقة مباشرة أثناء التصيير
نسخ الكائن المختار بالكاملتقادم لوحة التفاصيل بعد تعديل العنصرتخزين المعرّف selectedId والبحث بـ find
نسخ الخصائص داخل useStateتجاهل المكون الابن لتحديثات الأب اللاحقةقراءة الخاصية القادمة من الأب مباشرة
خلاصة المعرفة ومحطة الانتقال

ملخص الدرس

حصاد الدرس

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

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

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

مشاركة

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

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

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

المصطلحات4

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

0 / 4 مفهومةأول بطاقة، أول خطوة
01 Derived Value القيمة المشتقة
أي مجموع أو عداد أو قائمة مصفاة تُحسب لحظياً أثناء التصيير من الحالة أو الخصائص الموجودة.
للمراجعة
02 Impossible State الحالة المستحيلة منطقياً
اجتماع رايتين منطقيتين متناقضتين في وقت واحد كأن يكون الطلب قيد الإرسال ومكتمل النجاح معاً.
للمراجعة
03 Normalized State الحالة المسطحة المنظمة
تمثيل البيانات المتشعبة كمجموعات مسطحة مترابطة بالمعرّفات لتسهيل التحديث النقي دون تداخل عميق.
للمراجعة
04 Prop Mirroring نسخ الخاصية في الحالة
الخطأ المعماري المتمثل في تمرير خاصية الأب لـ useState مما يجمدها عند أول قيمة ويهمل تحديثات الأب.
للمراجعة

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

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

الاختصارات4

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

0 / 4 مفهومةأول بطاقة، أول خطوة
01 DRY DRY
Don’t Repeat Yourself
مبدأ عدم تكرار نفس المعلومة في أكثر من موضع والاكتفاء باشتقاق النتائج الحسابية منها.
للمراجعة
02 ID ID
Identifier
معرّف فريد مختصر يُحفظ في الحالة لاسترجاع أحدث نسخة من الكائن داخل المصفوفة الأصلية.
للمراجعة
03 UI UI
User Interface
طبقة العرض البصرية التي تبقى متسقة تلقائياً عند التخلص من متغيرات الحالة المكررة.
للمراجعة
04 JSON JSON
JavaScript Object Notation
صيغة البيانات الشجرية التي يفضل المهندسون تسطيحها عند إدارة التعديلات المتداخلة في الحالة.
للمراجعة

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

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

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

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

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

  2. افتح مثال EditableModuleSelector وعدّل اسم الوحدة المختارة لتتأكد من تحديث المعاينة لحظياً بفضل تخزين المعرّف فقط.

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

مساحة التحدي

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

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

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

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

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

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

متى يُفضّل جمع قيمتين معاً داخل كائن واحد في useState؟

القيم المتلازمة التي تتحدث دائماً في اللحظة نفسها مثل الإحداثيات أو العرض والارتفاع تُجمع في كائن واحد.

02

كيف تقضي على الحالات المتناقضة الناتجة عن تعدد الرايات المنطقية المنفصلة لحالة الإرسال؟

باستبدال الرايات المتفرقة بمتغير status نصي واحد يأخذ مرحلة واحدة محددة في كل وقت.

03

إذا كان المكون يملك الاسم الأول والأخير في الحالة، فما الطريقة الصحيحة للتعامل مع الاسم الكامل؟

حسابه كمتغير عادي أثناء التصيير مباشرة دون إنشاء متغير حالة ثالث مكرر.

04

تخزين مصفوفة عناصر السلة في الحالة مع إضافة متغير حالة منفصل لعددها يمثل تكراراً يعرض الواجهة لعدم التزامن.

صواب؛ لأن خاصية الطول للمصفوفة تعطي العدد الدقيق دائماً دون أي مخاطرة بنسيان التحديث.

05

في قائمة منتجات قابلة للتعديل تضم لوحة معاينة للمنتج المختار، ماذا يجب أن نخزن في الحالة لتمثيل الاختيار؟

تخزين المعرّف selectedId فقط والبحث عن المنتج الحي داخل المصفوفة أثناء التصيير.

06

ماذا يحدث إذا كتب المكون الابن useState(props.theme) ثم غيّر المكون الأب قيمة خاصية theme لاحقاً؟

تقرأ دالة useState القيمة الابتدائية عند التركيب الأول فقط فيتجاهل الابن التحديث الجديد القادم من الأب.

07

يسهم تسطيح هياكل الحالة شديدة التداخل إلى مجموعات مترابطة بالمعرّفات في جعل التحديثات النقية أقصر وأقل عرضة للأخطاء.

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

08

عندما تقصد عمداً استخدام خاصية الأب كقيمة بذرة أولية فقط لحالة محلية مستقلة، فما التسمية التوضيحية الموصى بها؟

بدء اسم الخاصية ببادئة مثل initialTitle أو defaultColor لتوضيح أنها تُقرأ في البداية فقط.

09

يمكن اشتقاق متغيرات منطقية مقروءة مثل isSending مباشرة أثناء التصيير من متغير المرحلة النصي الموحد status.

صواب؛ تجمع بذلك بين وضوح القراءة في JSX واستحالة تناقض الحالة.

10

ما القاعدة الذهبية التي تلخص فلسفة تقليل متغيرات الحالة في React؟

تخزين الحد الأدنى الضروري من البيانات الأولية المتغيرة واشتقاق كل ما عداها أثناء التصيير.