في هذا الدرس 6تصفّح المواضيع
عند استلام تصميم واجهة جديد وعينة بيانات JSON، لا يبدأ مهندس React المتمرس بنثر استدعاءات useState() عشوائياً في ملف ضخم واحد، بل يتبع المنهجية الهندسية المنظمة المكونة من خمس خطوات والمعروفة باسم التفكير بطريقة React.
الخطوة 1 — تقسيم الواجهة إلى شجرة مكونات هرمية: ارسم حدوداً واضحة حول كل جزء يؤدي مسؤولية واحدة محددة. في كتالوج الدورات التفاعلي تتشكل الشجرة طبيعياً من الحاضن FilterableCatalog وبداخله SearchBar وCourseTable الذي يعرض صفوف CourseRow.
function CourseRow({ course }) {
return (
<tr>
<td>{course.title}</td>
<td>{course.free ? 'Free' : 'Pro'}</td>
</tr>
);
}
الخطوة 2 — بناء النسخة الساكنة أولاً: قبل إضافة أي متغير حالة تفاعلي، ابنِ شجرة المكونات لتعرض البيانات التجريبية عبر الخصائص Props فقط دون استدعاء useState() على الإطلاق.
يفصل المهندسون هذه المرحلة عمداً لأن كتابة الهيكل الساكن تحتاج طباعة سريعة بلا تعقيد ذهني، بينما تحتاج إضافة التفاعل تفكيراً معمارياً هادئاً بأسطر قليلة.
function StaticCatalog({ courses }) {
return (
<div className="card">
<input placeholder="Search..." readOnly />
{courses.map((c) => (
<p key={c.id}>{c.title}</p>
))}
</div>
);
}
الخطوة 3 — تحديد التمثيل الأدنى والأكمل لحالة الواجهة: احصر كل البيانات الموجودة في الشاشة واختبر كلاً منها بثلاثة أسئلة حاسمة: (1) هل تبقى ثابتة بمرور الوقت؟ (2) هل تأتي من الأب عبر الخصائص؟ (3) هل يمكن حسابها من حالة أو خصائص أخرى؟
إذا كانت الإجابة «نعم» عن أي سؤال منها فهي ليست حالة! في كتالوجنا: قائمة الدورات الأصلية ثابتة، والقائمة المصفاة مشتقة حسابياً؛ فلا يبقى كحالة حقيقية سوى متغيرين اثنين فقط: نص البحث وخيار المجاني فقط.
الخطوة 4 — تحديد المكون المالك للحالة: لكل متغير حالة استخلصته في الخطوة الثالثة، حدد جميع المكونات التي تعتمد عليه في عرضها، ثم ضع الحالة في أقرب مكون أب مشترك يجمعها.
يحتاج SearchBar إلى قراءة نص البحث وخيار التصفية لعرضهما، ويحتاج CourseTable إلى القائمة المشتقة منهما؛ لذا يستقر خطافا useState() في الأب الجامع لهما FilterableCatalog.
function FilterableCatalog({ courses }) {
const [query, setQuery] = useState('');
const [freeOnly, setFreeOnly] = useState(false);
const visible = courses.filter((c) =>
(!freeOnly || c.free) &&
c.title.toLowerCase().includes(query.toLowerCase())
);
return <CourseTable courses={visible} />;
}
الخطوة 5 — إضافة التدفق العكسي للأحداث: تتدفق البيانات الآن نزولاً بانتظام من الأب إلى الأبناء، لكن الكتابة داخل SearchBar لا تستطيع بعدُ تغيير حالة الأب FilterableCatalog.
نغلق الحلقة التفاعلية بتمرير دوال التحديث نزولاً عبر الخصائص onQueryChange={setQuery} وonFreeOnlyChange={setFreeOnly}؛ فكل ضغطة مفتاح في الابن تستدعي دالة الأب فيتحدث الجدول المصفى لحظياً.
بدمج الخطوات الخمس يكتمل أمامنا تطبيق كتالوج الدورات القابل للبحث والتصفية بمعايير إنتاجية نظيفة: مكونات واضحة المسؤولية، وتسميات مربوطة بـ useId()، وصفر حالة مكررة، وتصفية فورية غير حساسة لحالة الأحرف مع رسالة لطيفة عند انعدام النتائج. جرّب التطبيق الكامل أدناه وراجع ملخص المنهجية في الجدول:
| خطوة المنهجية | السؤال الهندسي الذي تحسمه | المخرج البرمجي الفعلي |
|---|---|---|
| 1 و2. التقسيم والنسخة الساكنة | ما حدود المكونات وكيف تنزل الخصائص؟ | شجرة مكونات عرض ساكنة ونظيفة |
| 3. تحديد أصغر حالة | أي القيم متغيرة فعلاً وأيها مشتق حسابياً؟ | قائمة مختصرة بالحالة الحقيقية فقط |
| 4. تحديد مالك الحالة | من الأب المشترك المغذي لكل القراء؟ | استدعاء useState في الأب الجامع |
| 5. التدفق العكسي للأحداث | كيف تحدّث حقول الأبناء حالة الأب؟ | تمرير دوال التحديث عبر الخصائص |
function FilterableCatalog({ courses }) {
const [query, setQuery] = useState('');
const [freeOnly, setFreeOnly] = useState(false);
const visible = courses.filter((c) => ...);
return (
<div>
<SearchBar query={query} freeOnly={freeOnly}
onQuery={setQuery} onFree={setFreeOnly} />
<CourseTable courses={visible} />
</div>
);
}
ملخص الدرس
حصاد الدرسمراجعة مركّزة لأهم المفاهيم والقواعد الهندسية التي أتقنتها في هذا الدرس قبل التطبيق العملي
ماذا تعلّمت في هذا الدرس؟
أتقنت في هذا الدرس المنهجية الهندسية المتكاملة للتفكير بطريقة React عبر خطواتها الخمس: تقسيم شجرة المكونات، وبناء النسخة الساكنة، وعزل أصغر حالة حقيقية، وتسكينها في الأب المشترك، وربط التدفق العكسي للأحداث، مختتماً بذلك الوحدة الخامسة بنجاح. الخطوة التالية: انتقل الآن إلى الدرس رقم 28 «إدارة الحالات المركبة عبر خطاف useReducer» لمواصلة البناء التراكمي المتدرج في مسار React الحديث.
سجّل الدخول لحفظ تقدمك
تابع إنجاز المواضيع والمصطلحات والمهام، وكمّل من آخر خطوة على أي جهاز.
المصطلحات4
راجع المعنى، اشرحه لنفسك، ثم علّم البطاقة كمفهومة.
- 01 Thinking in React منهجية التفكير في React
- المنهجية الهندسية القياسية المكونة من خمس خطوات لتحويل التصاميم البصرية إلى شجرة مكونات تفاعلية منظمة.
- للمراجعة
- 02 Single Responsibility Principle مبدأ المسؤولية الواحدة
- تصميم كل مكون بحيث يختص بمسؤولية عرض أو هيكلة واحدة واضحة ومحددة.
- للمراجعة
- 03 Static Version النسخة الساكنة الأولية
- بناء واجهة العرض بالخصائص الثابتة أولاً للتحقق من سلامة التقسيم قبل إضافة منطق التفاعل.
- للمراجعة
- 04 Inverse Data Flow التدفق العكسي للأحداث
- تزويد المكونات الفرعية بدوال تحديث الأب عبر الخصائص لتصعد تفاعلات المستخدم للأعلى بنظافة.
- للمراجعة
لا توجد بطاقات تطابق البحث والتصفية.
اقرأ البطاقات بحرية. سجّل الدخول لحفظ تقدم مراجعتك.
الاختصارات4
راجع المعنى، اشرحه لنفسك، ثم علّم البطاقة كمفهومة.
- 01 SRP SRP
- Single Responsibility Principle
- مبدأ هندسة البرمجيات الموجه لتقسيم المكونات الكبيرة إلى وحدات مركزة يسهل اختبارها.
- للمراجعة
- 02 DRY DRY
- Don’t Repeat Yourself
- المبدأ الحاكم للخطوة الثالثة بالاكتفاء بالحالة الأولية واشتقاق القوائم المصفاة دون تكرار.
- للمراجعة
- 03 JSON JSON
- JavaScript Object Notation
- نموذج البيانات المهيكلة الذي يتطابق تقسيمه الهرمي بسلاسة مع شجرة مكونات الواجهة.
- للمراجعة
- 04 UI UI
- User Interface
- التصميم البصري الذي يبدأ مقسماً إلى صناديق في الخطوة الأولى وينبض بالتفاعل في الخطوة الخامسة.
- للمراجعة
لا توجد بطاقات تطابق البحث والتصفية.
اقرأ البطاقات بحرية. سجّل الدخول لحفظ تقدم مراجعتك.
مهامك قبل الاختبار
خطوة صغيرة كل مرة. وإنجاز تقدر ترجع له.
-
افتح مثال FilterableCatalog وأضف متغير حالة ثالث لاختيار التصنيف في الأب المشترك واربطه بشريط البحث ومعادلة التصفية.
-
اعرض عدد الدورات المطابقة من إجمالي الدورات بالاعتماد على خاصية الطول المشتقة دون إضافة أي متغير حالة جديد.
تأشير المهمة إقرار منك بإتمامها، وليس تصحيحًا آليًا للكود. يُحفظ تقدمك في حسابك.
اختبر فهمك.
ووصلها للإتقان.
كل سؤال خطوة لقدّام. اختار، اكتب كود، وشوف نتيجتك فورًا.
أكمل المهام، واجمع كل الإجابات الصحيحة. أقل من 100%؟ راجع وأعد المحاولة.
الأسئلة متاحة للاطلاع. سجّل الدخول للتفاعل وحفظ تقدمك.
لمحة عن التحدي10 أسئلة تنتظرك +
ما الخطوة الأولى في منهجية التفكير بطريقة React الرسمية؟
تبدأ المنهجية بتقسيم تصميم الواجهة إلى شجرة مكونات هرمية واضحة الحدود والمسؤوليات.
في الخطوة الثانية لبناء النسخة الساكنة، كيف تستقبل المكونات البيانات التجريبية لعرضها؟
تعتمد النسخة الساكنة على تمرير البيانات نزولاً عبر الخصائص فقط دون استخدام أي حالة تفاعلية بعد.
في جدول المنتجات القابل للبحث، يجب حفظ المصفوفة المصفاة الناتجة داخل متغير حالة خاص بها في useState.
خطأ؛ القائمة المصفاة قيمة مشتقة تُحسب أثناء التصيير من القائمة الأصلية ونص البحث وخيار التصفية.
أي من البيانات التالية يُعد حالة واجهة حقيقية داخل تطبيق كتالوج الدورات القابل للتصفية؟
نص البحث الذي يكتبه المستخدم يتغير بمرور الوقت ولا يمكن اشتقاقه من بيانات أخرى.
لماذا توضع حالة نص البحث داخل المكون الأب FilterableCatalog بدلاً من حبسها داخل SearchBar وحده؟
لأن جدول الدورات الشقيق يحتاج أيضاً إلى نص البحث لتصفية صفوفه، فتوضع الحالة في الأب المشترك بينهما.
ماذا تضيف الخطوة الخامسة الخاصة بالتدفق العكسي للأحداث إلى شجرة مكونات React؟
تمرير دوال تحديث الحالة كخصائص للأبناء لتتمكن حقول الإدخال الفرعية من تحديث حالة الأب.
يرشد مبدأ المسؤولية الواحدة إلى تقسيم المكون المتضخم متعدد المهام إلى مكونات فرعية أصغر وأوضح تركيزاً.
صواب؛ المكونات ذات المهمة الواحدة أسهل في القراءة والاختبار وإعادة التوظيف.
البيانات القادمة من الأب عبر الخصائص لا ينبغي نسخها في متغير حالة محلي في الابن.
صواب؛ فالبيانات الواردة عبر الخصائص ليست حالة محلية للمكون المستقبِل.
كيف تجعل البحث النصي مريحاً ودقيقاً للمستخدم داخل تعبير التصفية المشتق؟
تنظيف الفراغات وتوحيد الأحرف الصغيرة لكلا النصين قبل فحص الاحتواء بدالة includes.
إذا احتاج مكونان إلى حالة مشتركة ولم يوجد مكون أب حالي يناسب امتلاكها معمارياً، فبماذا توصي الخطوة الرابعة؟
إنشاء مكون أب حاضن جديد يعلوهما وتكون مهمته احتضان وتوزيع تلك الحالة المشتركة.