في هذا الدرس 6تصفّح المواضيع
تشترك فهارس المنتجات وروابط القوائم الجانبية وسجلات الإشعارات في بنية واحدة؛ وهي تكرار نفس القالب البصري لكل سجل داخل مجموعة بيانات. بدلاً من نسخ البطاقات يدوياً، تولّد React القوائم ديناميكياً من مصفوفات الكائنات عبر دوال المصفوفات القياسية غير المغيِّرة في JavaScript.
لعرض مصفوفة سجلات على الشاشة، نستدعي الدالة items.map((item) => <li key={item.id}>...</li>) داخل أقواس JSX المعقوفة. وترسم React عناصر المصفوفة الناتجة بالترتيب، مع ضرورة تزويد العنصر الخارجي المعاد داخل map() بخاصية معرّف فريد key لتمييز كل سجل.
const tracks = [
{ id: 't1', name: 'HTML5 Markup', count: 53 },
{ id: 't2', name: 'Modern React', count: 51 },
];
function TrackList() {
return <ul>{tracks.map((t) => (
<li key={t.id}>{t.name} ({t.count})</li>
))}</ul>;
}
انتبه جيداً لنوع الأقواس التي تلي سهم الدالة داخل map()! فاستخدام الأقواس الهلالية (item) => (<li>...</li>) ينفذ إرجاعاً ضمنياً تلقائياً للعنصر. أما إذا فتحت أقواساً معقوفة (item) => { ... } لحساب متغير محلي، فيجب حتماً كتابة كلمة return صراحةً، وإلا أعادت الدالة قيماً فارغة واختفت القائمة!
عندما ترغب في عرض السجلات المحققة لشرط محدد فقط، كالمنتجات المتوفرة بالمخزون أو الدورات المنشورة، استدعِ دالة filter() أولاً لاستخلاص مصفوفة فرعية مطابقة، ثم أردفها بدالة map() لتحويل تلك السجلات إلى عناصر عرض.
function InStockCatalog({ items }) {
const ready = items.filter((i) => i.inStock);
return (
<div className="rx-stack">
{ready.map((i) => (
<div key={i.id}>{i.name} — ${i.price}</div>
))}
</div>
);
}
كلما زادت تفاصيل العنصر الواحد من صور وشارات وبيانات فرعية، افصل بنيته في مكون فرعي مستقل مثل <WorkshopCard />. وتذكر القاعدة الذهبية دائماً؛ وهي وضع خاصية key مباشرة على استدعاء <WorkshopCard key={w.id} /> داخل حلقة map() وليس على الوسم الداخلي داخل ملف المكون الابن.
function WorkshopItem({ title, hours }) {
return <li>{title} ({hours}h)</li>;
}
function WorkshopList({ list }) {
return (
<ul>
{list.map((w) => (
<WorkshopItem key={w.id} {...w} />
))}
</ul>
);
}
كثيراً ما تكون مصفوفات البيانات فارغة في بيئة الإنتاج؛ كمستخدم جديد بلا إشعارات أو تصفية بحث لا تطابق أي دورة. احرص دوماً على فحص items.length === 0 لعرض حالة فارغة واضحة ومفيدة بدلاً من ترك مساحة بيضاء مربكة. يلخص الجدول التالي أدوات عرض القوائم:
| عملية المصفوفة | القيمة المُعادة | دورها في عرض قوائم React |
|---|---|---|
array.map(fn) | مصفوفة جديدة من عناصر JSX | تحويل كل كائن بيانات إلى مكون React مزود بمفتاح |
array.filter(fn) | مصفوفة فرعية مطابقة للشرط | انتقاء السجلات المطلوبة بنقاء قبل رسمها على الشاشة |
items.length === 0 | قيمة منطقية صريحة | رصد القوائم الخالية لعرض رسالة إرشادية واضحة |
array.forEach(fn) | القيمة undefined | غير صالحة داخل JSX لأنها لا تعيد مصفوفة عناصر |
function SearchResults({ courses }) {
if (courses.length === 0) {
return <p>No matching courses found.</p>;
}
return (
<ul>
{courses.map((c) => (
<li key={c.id}>{c.title}</li>
))}
</ul>
);
}
ملخص الدرس
حصاد الدرسمراجعة مركّزة لأهم المفاهيم والقواعد الهندسية التي أتقنتها في هذا الدرس قبل التطبيق العملي
ماذا تعلّمت في هذا الدرس؟
تعلمت في هذا الدرس تحويل مصفوفات البيانات إلى قوائم مكونات ديناميكية بدالة map، وميزت الإرجاع الضمني والصريح بالدوال السهمية، وطبقت التصفية المسبقة بدالة filter، وفصلت مكون العنصر المفرد، وصممت واجهة القوائم الفارغة. الخطوة التالية: انتقل الآن إلى الدرس رقم 14 «أهمية خاصية المفتاح الفريد key في قوائم React» لمواصلة البناء التراكمي المتدرج في مسار React الحديث.
سجّل الدخول لحفظ تقدمك
تابع إنجاز المواضيع والمصطلحات والمهام، وكمّل من آخر خطوة على أي جهاز.
المصطلحات4
راجع المعنى، اشرحه لنفسك، ثم علّم البطاقة كمفهومة.
- 01 Array.prototype.map() دالة التحويل map
- دالة مصفوفات قياسية غير مغيرة تحول كل عنصر بيانات إلى عنصر JSX داخل مصفوفة جديدة.
- للمراجعة
- 02 Array.prototype.filter() دالة التصفية filter
- دالة مصفوفات نقية تعيد مصفوفة جديدة تضم فقط العناصر التي تحقق شرط الاختبار المنطقي.
- للمراجعة
- 03 Implicit Return الإرجاع الضمني السهمي
- صياغة مختصرة في الدوال السهمية تعيد قيمة التعبير مباشرة عند عدم استخدام أقواس الكتلة المعقوفة.
- للمراجعة
- 04 Empty State UI واجهة القائمة الفارغة
- عنصر إرشادي واضح يُعرض للمستخدم عندما تكون مصفوفة البيانات الأصلية أو المصفاة خالية من النتائج.
- للمراجعة
لا توجد بطاقات تطابق البحث والتصفية.
اقرأ البطاقات بحرية. سجّل الدخول لحفظ تقدم مراجعتك.
الاختصارات4
راجع المعنى، اشرحه لنفسك، ثم علّم البطاقة كمفهومة.
- 01 JSX JSX
- JavaScript XML
- صياغة تدعم تلقائياً رسم مصفوفات عناصر React المعادة من دالة map داخل الأقواس المعقوفة.
- للمراجعة
- 02 JSON JSON
- JavaScript Object Notation
- التنسيق القياسي لبيانات الواجهات البرمجية والذي تُحول مصفوفاته إلى قوائم مكونات في React.
- للمراجعة
- 03 UX UX
- User Experience
- تجربة المستخدم، وتتحسن جوهرياً بتوفير رسائل إرشادية واضحة عند خلو القوائم من النتائج.
- للمراجعة
- 04 ES6 ES6
- ECMAScript 2015
- معيار اللغة الذي وفّر الدوال السهمية المختصرة المستخدمة بكثافة داخل دوال map وfilter.
- للمراجعة
لا توجد بطاقات تطابق البحث والتصفية.
اقرأ البطاقات بحرية. سجّل الدخول لحفظ تقدم مراجعتك.
مهامك قبل الاختبار
خطوة صغيرة كل مرة. وإنجاز تقدر ترجع له.
-
افتح مثال InStockCatalog في محرر التجريب وعدّل شرط التصفية ليجمع بين التوفر والسعر الأقل من 100 دولار.
-
غيّر نص خاصية البحث query في مثال SearchResults إلى "Foundations" ولاحظ تحول العرض من رسالة الخلو إلى القائمة.
تأشير المهمة إقرار منك بإتمامها، وليس تصحيحًا آليًا للكود. يُحفظ تقدمك في حسابك.
اختبر فهمك.
ووصلها للإتقان.
كل سؤال خطوة لقدّام. اختار، اكتب كود، وشوف نتيجتك فورًا.
أكمل المهام، واجمع كل الإجابات الصحيحة. أقل من 100%؟ راجع وأعد المحاولة.
الأسئلة متاحة للاطلاع. سجّل الدخول للتفاعل وحفظ تقدمك.
لمحة عن التحدي10 أسئلة تنتظرك +
ما الدالة القياسية في JavaScript التي تحوّل مصفوفة كائنات إلى مصفوفة عناصر JSX قابلة للعرض في React؟
تُنتج دالة map مصفوفة جديدة تحتوي على عناصر JSX المقابلة لكل سجل في المصفوفة الأصلية.
لماذا لا يظهر أي عنصر على الشاشة عند كتابة {items.forEach((item) => <li>{item.name}</li>)}؟
لأن الدالة forEach تعيد القيمة undefined دائماً ولا تعيد مصفوفة عناصر كما تفعل map.
ما الخطأ البرمجي في كتابة items.map((item) => { <li key={item.id}>{item.title}</li> })؟
فتح الأقواس المعقوفة بعد السهم ينشئ كتلة دالة تتطلب كتابة كلمة return صراحةً لإرجاع العنصر.
ما دالة المصفوفات التي تنتج مصفوفة فرعية للدورات المنشورة فقط دون تعديل المصفوفة الأصلية؟
تعيد دالة filter مصفوفة جديدة تضم العناصر المحققة للشرط فقط مع بقاء الأصل سليماً.
عند استدعاء مكون فرعي <ProductCard /> داخل حلقة products.map()، أين يجب وضع خاصية key؟
يوضع المفتاح مباشرة على وسم المكون <ProductCard key={p.id} /> المعاد داخل دالة map.
تُنشئ كل من الدالتين filter() وmap() مصفوفة جديدة دون إحداث أي تعديل مباشر في المصفوفة الأصلية.
صواب؛ فكلتاهما دالتان نقيتان تحافظان على سلامة المصفوفة الأصلية تماماً.
يساعد التحقق عبر if (items.length === 0) قبل رسم القائمة على تجنب عرض صندوق فارغ مبهم للمستخدم.
صواب؛ فإظهار رسالة واضحة عند خلو القائمة يحسّن تجربة المستخدم ويمنع الالتباس.
ما التحذير الشهير الذي تطبعه React في سجل المتصفح عند عرض قائمة بـ map() دون تحديد خاصية key؟
تطبع React تحذيراً ينبه إلى وجوب امتلاك كل عنصر في القائمة لخاصية مفتاح key فريدة.
تعتمد الصياغة (item) => (<Card key={item.id} />) على ميزة الإرجاع الضمني في الدوال السهمية.
صواب؛ فالأقواس الهلالية تحيط بتعبير JSX المُعاد تلقائياً دون الحاجة لكلمة return.
لماذا تُعد تصفية المصفوفة بـ filter() قبل map() أنظف هندسياً من إرجاع null داخل map()؟
لأنها تمنحك العدد الفعلي الدقيق للنتائج وتفصل منطق الانتقاء عن منطق بناء عناصر الواجهة.