الإقليم ١٢ — ليلة الافتتاح
من هنا فصاعداً، استعمل React الحقيقي فقط — لا نُسخك المصغّرة (useStateNano, cvaNano, محرّك h/createDom اليدوي). بنيتَ تلك النسخ لتفهم الداخل؛ الآن تفهمه، فاستعمل الأداة الحقيقية بثقةٍ كاملة — تعرف بالضبط ماذا تفعل تحت كل استدعاء.
يبني فوق: كل الأقاليم الثلاثة عشر. النطاق: لا آلية جديدة هنا — فقط رؤية كل ما بنيتَه يعمل معاً، في تطبيقٍ واحد، ومسارِ تشخيصٍ يثبت أنك تملك النماذج الذهنية لا الحفظ. يفتح: لا شيء — هنا تُقفَل الشجرة.
الجزء الأول: مسار بيانةٍ واحدة عبر الأقاليم كلها
قبل اللغز الأخير، تتبّع بيدك (كتابةً، لا برمجة) رحلة نقرة "أضف مهمّة" واحدة، من اللحظة صفر حتى استقرار الشاشة، مروراً بكل إقليمٍ بنيتَه:
لاحظ: لا خطوة واحدة هنا "سحرية". كل خطوةٍ اسمٌ بنيتَه بيدك، ورأيته يعمل (أو ينكسر، ثم أصلحته) بعينك في إقليمه. هذا ما يعنيه "امتلاك النموذج الذهني": تقدر تُكمل هذه القائمة لأي فعلٍ آخر في أي تطبيق React تراه لأول مرة.
الجزء الثاني: تشخيصٌ بالنموذج الذهني (بلا كود)
لكل عرضٍ أدناه: حدّد الإقليم المسؤول، والآلية الدقيقة المكسورة — بلا أن تكتب أو ترى أي كود. هذا يختبر إن كنتَ تملك النموذج، لا الحفظ.
- زرٌّ يعمل في أول نقرة، وبعد ظهور رسالة خطأ يصبح "ميتاً" تماماً لا يستجيب للنقرات التالية.
- حقل بحثٍ يعرض أحياناً نتائج مطابقةً لما كتبتَه قبل حرفين، لا لما تكتبه الآن، تحديداً حين تكتب بسرعة.
- قائمة عناصر فيها حقول نصّية قابلة للتعديل؛ إضافة عنصرٍ جديدٍ في أول القائمة تجعل قيمة كتبتَها في عنصرٍ تظهر فجأة في عنصرٍ آخر مجاور.
- مكوّنٌ صغير جداً (يعرض فقط اسم الثيم الحالي) يُعاد رسمه في كل مرّة يصل فيها إشعارٌ جديد، رغم أن الثيم نفسه لم يتغيّر أبداً.
- أثرٌ فيه
setIntervalيطبع كل ثانية نفس القيمة الأولى لمتغيّر حالة، رغم أن القيمة المعروضة فعلياً على الشاشة تتحدّث بشكل صحيح تماماً أمام عينيك. - مكوّن
<Card>"جاهز" من نظام تصميمكم؛ حاولتَ تمريرrefله لتُركّز عليه برمجياً بعد ظهور خطأ تحقّق، لكن.currentيبقىnullدائماً. - صفحةٌ محميّة بحارس مصادقة؛ الوصول لها عبر النقر داخل التطبيق يعمل ويُحوّل صحيحاً، لكن كتابة رابطها مباشرة في شريط العنوان (Refresh) تُظهر المحتوى المحمي قبل أن يظهر أي تحويل، للحظة، حتى للمستخدم غير المسجَّل دخوله.
- مكوّنٌ فيه ثلاثة
useStateمستقلّة لحقلٍ ثلاثي الخطوات؛ اختبارٌ يدويٌّ سريعٌ للنقر على "التالي" ثم "رجوع" بسرعة يضع التطبيق في تركيبة حالةٍ لم تكن تتوقّعها أبداً ولا تعرف كيف حدثت. - الكود يمرّ
tsc --noEmitبصفر أخطاء، لكن تشغيله الفعلي في المتصفّح يُغرق تبويب Network بمئات الطلبات في الثانية الأولى. - عنصرٌ يُفترض أنه رابطٌ حقيقي (يبدو كزر تماماً)؛ فحص DOM يكشف عنصرين متداخلين (
<button><a>...</a></button>) بدل عنصرٍ واحد.
لا تنتقل للغز الأخير قبل أن تكتب إجابةً لكل الأعراض العشرة، ولو بجملةٍ واحدة لكل واحد. (كل عرضٍ هنا صمّم ليطابق تماماً بقّةً بنيتَها بيدك وأصلحتها في إقليمها — لو تعثّرتَ في واحدة، ارجع لإقليمها وأعد تجربة لغزها بنفسك، لا تقرأ الحل من هنا.)
الجزء الثالث: اللغز الأخير — لوحة مهامٍ كاملة
ابنِ لوحة مهامٍ صغيرة (نفس فكرة الإقليم ٠، لكن الآن بكل ما تعلّمته)، مشروع Vite+React+TS حقيقي من الصفر. المتطلّبات إلزامية كلّها — كل واحدة تفرض استعمال تقنيةٍ من إقليمٍ محدَّد، بلا اختصار:
| المتطلَّب | يفرض استعمال |
|---|---|
جلب قائمة المهام عند الظهور عبر خطافٍ مخصّص عام (useAsync-مثل) | ٣، ٦ |
| إضافة مهمّة عبر نموذجٍ بمعالج حدث مباشر (لا أثر)، بتحقّق حقلٍ فارغ | ٤ |
| قائمة المهام بمفاتيح صحيحة، تحقّق سلامتها بإدراجٍ في المنتصف | ٠ |
نموذج إضافة/تعديل متعدّد الحقول (عنوان، أولوية، تاريخ استحقاق) بـuseReducer يمنع انتقالاتٍ غير صالحة (كإرسالٍ أثناء إرسالٍ سابق) | ٥ |
حقل العنوان يُركَّز تلقائياً عند فتح النموذج (useRef) | ٥ |
عدّاد "المتبقّي" محسوبٌ بـuseMemo، تحقّق أنه لا يُعاد حسابه إلا عند تغيّر المهام فعلاً | ٥ |
زرّ <Button> بنظام variant/size (CVA-مثل)، مع forwardRef، ومستخدَمٌ مرّةً واحدة على الأقل بـasChild كرابطٍ حقيقي | ٩ |
| قناة Context للثيم (نادرة التغيّر)، منفصلة تماماً عن أي حالةٍ عالية التردّد إن وُجدت | ٧ |
هيكلة features/tasks/{pages,components,hooks,api.ts} بحدّ شكل/منطق واضح | ٨ |
مساران على الأقل (/ للوحة، /tasks/:id للتفاصيل) بإطارٍ مشترك عبر Outlet، وحارسٌ يحمي مساراً واحداً على الأقل بشرطٍ وهمي | ١٠ |
eslint.config.js حقيقيّ يعمل بصفر أخطاء وتحذيرات على كامل الكود | ١١ |
التحدّي الأخير (اختياري لكن موصى به بشدّة): بعد إتمام التطبيق، ازرع عمداً واحدةً من البقّات العشر في الجزء الثاني داخل نسخةٍ منفصلة من كودك. اترك التطبيق يوماً كاملاً (أو أعطه لصديقٍ يعرف React أساسياً)، ثم شخّصه من الأعراض فقط، بلا أن تنظر للكود أولاً. إن استطعتَ تحديد الإقليم والآلية بدقّة قبل فتح الكود — أنهيتَ هذا المنهج فعلياً بامتلاك النموذج، لا حفظ الحل.
الخلاصة — الشجرة الآن مكتملة
راجع خريطة README.md وشجرة appendix/skill-tree.md. كل عقدةٍ فيها بنيتَها بيدك، من عبثٍ يدويٍّ بالـDOM في الإقليم ٠ حتى مشروعٍ كاملٍ منظَّمٍ ومفحوصٍ آلياً هنا. لا توجد بذرة غموضٍ بعد هذا الإقليم — كل باب فُتح، أُغلق.
ما تُرك خارج هذا المنهج عمداً (بذورٌ لمنهجٍ لاحق، لا نقصٌ): دواخل React الأعمق (المجدوِل والأولويات — concurrent features، lanes)؛ الاختبار (Jest/React Testing Library/Playwright)؛ إدارة حالةٍ خارجية باشتراكاتٍ انتقائية حقيقية (كما لمّحنا في الإقليم ٧)؛ العرض من الخادم (SSR/Next)؛ والأداء المتقدّم (code-splitting، lazy، Suspense).
الوصلة بمشروعك
لوحة المهام التي بنيتَها هنا بمعزلٍ تام عن أي ريبو حقيقي تشترك في بنيتها الجوهرية مع مشروع الفرونت عندكم (SelfLab) لسببٍ بسيط: كلاهما يحلّ نفس فئة المشكلة (تطبيق ويب تفاعلي، بمصادقةٍ، وبنظام تصميم، وهيكلةٍ حسب الميزة). لهذا اخترنا كل نطاقٍ في هذا المنهج من الأساس — ليس لأنه "React عموماً"، بل لأنه بالضبط ما يحتاجه مشروعٌ بهذا الشكل. الفرق أنك الآن لا تقرأ كودهم وتصدّق أنه صحيح؛ تملك المعيار لتحكم بنفسك: هل هذا الاستخدام لـuseEffect تزامنٌ حقيقي أم فعلٌ متخفٍّ؟ هل هذا المكوّن "شكل" نظيف أم يخفي منطقاً يجب استخراجه؟ هل هذا الزرّ يتبع نظام variants أم صنفٌ عشوائي جديد؟
هذه الأسئلة — لا حفظ أي API — هي ما بناه هذا المنهج فيك.