في هذا الدرس 6تصفّح المواضيع
تخيّل مجلداً يضم عدة ملفات بلا أسماء، وتُعرف فقط بترتيبها الأول والثاني والثالث؛ فإذا حُذف الملف الأول، سيتعذر تمييز أي ملف أُزيل وأي ملف بقي! تؤدي خاصية key في React دور الاسم الفريد الدائم لكل عنصر في المصفوفة عبر التصييرات المتعاقبة، مما يمكّن خوارزمية المطابقة من معرفة العنصر المضاف أو المحذوف أو المنقول بدقة تامة.
من أين نستمد المفاتيح الصحيحة هندسياً؟ اعتمد دائماً على المعرّفات الفريدة النابعة من أصل البيانات:
- مفاتيح قواعد البيانات: المعرّفات القادمة من الخادم مثل
course.idأو الاسم اللطيف الفريدlesson.slug. - البيانات المنشأة محلياً: ولّد معرّفاً فريداً مرة واحدة فقط لحظة إنشاء الكائن عبر دالة
crypto.randomUUID()خارج جسم التصيير.
const nodes = [
{ id: 'eu-1', host: 'Frankfurt', ms: 18 },
{ id: 'me-2', host: 'Riyadh', ms: 11 },
];
function ClusterList() {
return <div>{nodes.map((n) => (
<p key={n.id}>{n.host}: {n.ms}ms</p>
))}</div>;
}
يلجأ بعض المبتدئين لإسكات تحذير المتصفح عبر كتابة key={index} باستخدام فهرس المصفوفة. في الواقع، يؤدي استخدام الفهرس في القوائم القابلة للفرز أو الحذف أو الإضافة في البداية إلى أعطال خفية خطيرة؛ إذ تنزاح أرقام الفهارس فتظن React أن العنصر الجديد في الموقع صفر هو نفس العنصر القديم، فتحتفظ بنصوص الحقول وحالات العناصر في السطر الخطأ!
الأشد ضرراً من فهرس المصفوفة هو توليد مفتاح عشوائي أثناء الرسم مثل كتابة key={Math.random()} داخل دالة map()! لأن هذه الدالة تنتج قيمة مختلفة في كل تصيير، فتفترض React أن جميع العناصر القديمة قد حُذفت وتهدم عقد DOM بالكامل وتعيد بناءها من الصفر، مما يفقد التركيز داخل الحقول ويدمر الأداء.
تحتاج أحياناً لإرجاع عنصرين شقيقين لكل سجل في المصفوفة دون إفساد الهيكل الدلالي بغلاف <div> زائد، مثل زوج المصطلح <dt> والتعريف <dd> داخل قائمة <dl>. وبما أن الصيغة المختصرة <> لا تقبل سمات، نستورد Fragment من مكتبة react ونكتب الصيغة الصريحة <Fragment key={item.id}>.
import { Fragment } from 'react';
function GlossaryList({ terms }) {
return (
<dl>{terms.map((t) => (
<Fragment key={t.id}>
<dt>{t.name}</dt>
<dd>{t.meaning}</dd>
</Fragment>
))}</dl>
);
}
تكتمل مهارتك في إدارة المفاتيح بقاعدتين حاسمتين؛ الأولى أن تفرد المفتاح مطلوب بين العناصر الشقيقة داخل القائمة الواحدة فقط ولا يضر تشابه المعرفات بين قائمتين منفصلتين في الصفحة. والثانية أن React تستهلك خاصية key داخلياً ولا تمررها أبداً داخل كائن props؛ فإذا احتاج المكون الابن لقراءة المعرّف، مرره كخاصية صريحة مستقلة مثل ticketId={t.id}. قارن بين مصادر المفاتيح في الجدول التالي:
| مصدر المفتاح key | الثبات عبر التصييرات | الحكم الهندسي في React |
|---|---|---|
معرّف قاعدة البيانات item.id | ثابت بنسبة 100% مع الفرز والتصفية | المعيار القياسي المعتمد لكافة القوائم |
| معرّف UUID عند إنشاء الكائن | ثابت طوال عمر السجل في الذاكرة | ممتاز للبيانات المنشأة محلياً في المتصفح |
فهرس المصفوفة index | ينزاح فور الإضافة أو الحذف أو الفرز | تجنبه في القوائم المتغيرة أو التفاعلية |
دالة Math.random() بالعرض | يتغير في كل تصيير ويهدم العناصر | محظور تماماً — يدمر الأداء وحالة الحقول |
function TicketRow({ code, summary }) {
return <div>#{code}: {summary}</div>;
}
function TicketBoard({ tickets }) {
return (
<div className="rx-stack">
{tickets.map((t) => (
<TicketRow key={t.id} code={t.id} {...t} />
))}
</div>
);
}
ملخص الدرس
حصاد الدرسمراجعة مركّزة لأهم المفاهيم والقواعد الهندسية التي أتقنتها في هذا الدرس قبل التطبيق العملي
ماذا تعلّمت في هذا الدرس؟
استوعبت في هذا الدرس كيف تحافظ خاصية key على هوية العناصر أثناء المطابقة، واخترت المعرّفات الثابتة بدلاً من الفهرس المتغير والدوال العشوائية، وكتبت Fragment الصريح المزود بمفتاح، ومررت المعرّف كخاصية مستقلة عند الحاجة لعرضه. الخطوة التالية: انتقل الآن إلى الدرس رقم 15 «نقاء المكونات وتدفق البيانات أحادي الاتجاه» لمواصلة البناء التراكمي المتدرج في مسار React الحديث.
سجّل الدخول لحفظ تقدمك
تابع إنجاز المواضيع والمصطلحات والمهام، وكمّل من آخر خطوة على أي جهاز.
المصطلحات4
راجع المعنى، اشرحه لنفسك، ثم علّم البطاقة كمفهومة.
- 01 Key Prop خاصية المفتاح key
- معرّف نصي أو رقمي خاص تعتمد عليه React لتتبع هوية عناصر القائمة ومطابقتها بين التصييرات المتتالية.
- للمراجعة
- 02 Keyed Fragment غلاف Fragment بمفتاح
- الصيغة الصريحة لمكون التجميع التي تقبل خاصية key لإرجاع عدة عناصر شقيقة دون إضافة حاوية زائدة.
- للمراجعة
- 03 Identity Drift انزياح هوية العناصر
- خلل ينتج عن استخدام فهرس المصفوفة كمفتاح حين تتغير مواقع العناصر فتقترن حالة العنصر القديم بسجل خاطئ.
- للمراجعة
- 04 Sibling Uniqueness التفرد بين الأشقاء
- قاعدة اشتراط عدم تكرار المفتاح داخل نفس المصفوفة فقط، مع جواز تشابهه في قائمة أخرى مستقلة.
- للمراجعة
لا توجد بطاقات تطابق البحث والتصفية.
اقرأ البطاقات بحرية. سجّل الدخول لحفظ تقدم مراجعتك.
الاختصارات4
راجع المعنى، اشرحه لنفسك، ثم علّم البطاقة كمفهومة.
- 01 UUID UUID
- Universally Unique Identifier
- معرّف قياسي فريد عالمياً يُولّد عند إنشاء السجلات محلياً لضمان ثبات خاصية key.
- للمراجعة
- 02 DOM DOM
- Document Object Model
- تحتفظ عقدها بتركيز المؤشر وتُحدّث بأقل تكلفة ممكنة عند تزويد قوائم React بمفاتيح مستقرة.
- للمراجعة
- 03 PK PK
- Primary Key
- المفتاح الأساسي للسجل في قاعدة البيانات، ويُعد المصدر الأكثر موثوقية لخاصية key في الواجهة.
- للمراجعة
- 04 JSX JSX
- JavaScript XML
- يتطلب كتابة اسم المكون Fragment صراحةً بدلاً من القوسين الفارغين عند تمرير سمة key.
- للمراجعة
لا توجد بطاقات تطابق البحث والتصفية.
اقرأ البطاقات بحرية. سجّل الدخول لحفظ تقدم مراجعتك.
مهامك قبل الاختبار
خطوة صغيرة كل مرة. وإنجاز تقدر ترجع له.
-
افتح مثال GlossaryList في محرر التجريب وأضف مصطلحاً ثالثاً بمعرّف فريد وتحقق من نظافة قائمة التعريفات.
-
افحص مثال TicketBoard لملاحظة كيف تخدم key المطابقة الداخلية بينما تعرض ticketCode رقم التذكرة على الشاشة.
تأشير المهمة إقرار منك بإتمامها، وليس تصحيحًا آليًا للكود. يُحفظ تقدمك في حسابك.
اختبر فهمك.
ووصلها للإتقان.
كل سؤال خطوة لقدّام. اختار، اكتب كود، وشوف نتيجتك فورًا.
أكمل المهام، واجمع كل الإجابات الصحيحة. أقل من 100%؟ راجع وأعد المحاولة.
الأسئلة متاحة للاطلاع. سجّل الدخول للتفاعل وحفظ تقدمك.
لمحة عن التحدي10 أسئلة تنتظرك +
لماذا تشترط مكتبة React تزويد عناصر المصفوفات المرسومة بخاصية مفتاح key فريدة؟
لمنح كل عنصر هوية ثابتة عبر التصييرات تمكّن React من تتبع العناصر المضافة أو المحذوفة أو المنقولة بدقة.
أي قيمة تُعد الخيار الأفضل لخاصية key عند عرض قائمة دورات قادمة من قاعدة البيانات؟
معرّف السجل الفريد الثابت في قاعدة البيانات مثل course.id هو الخيار القياسي الأمثل.
ما الخلل الذي يقع عند استخدام key={index} في قائمة تُضاف إليها عناصر جديدة في المقدمة؟
تنزاح الفهارس الرقمية فتقرن React حالة الحقول والعناصر القديمة بالسجل الجديد الخاطئ.
لماذا يُحظر تماماً كتابة key={Math.random()} أثناء رسم القائمة داخل دالة المكون؟
لأن تغير المفتاح في كل تصيير يجبر React على هدم وإعادة إنشاء كافة عقد القائمة وفقدان التركيز.
كيف تمرر خاصية key عندما يعيد كل عنصر قائمة وسمي <dt> و<dd> متجاورين دون إضافة <div> زائد؟
نستورد Fragment من مكتبة react ونغلّف العنصرين بالصيغة الصريحة <Fragment key={item.id}>.
داخل دالة المكون الابن TicketRow(props)، تعيد قراءة props.key قيمة المفتاح الممررة من الأب.
خطأ؛ تستهلك React خاصية key داخلياً ولا تمررها ضمن كائن props، لذا نمرر خاصية صريحة إضافية عند الحاجة.
يُشترط تفرد قيمة key بين العناصر الشقيقة في نفس المصفوفة فقط، ولا يُشترط تفردها عبر قوائم أخرى منفصلة بالصفحة.
صواب؛ فالمطابقة تقارن العناصر الشقيقة داخل نفس الحاوية فقط.
تقبل الصيغة المختصرة الفارغة <>...</> تمرير سمة المفتاح key={item.id} بداخلها مباشرة.
خطأ؛ فالصيغة المختصرة لا تقبل أي سمات إطلاقاً ويلزم استخدام <Fragment key={item.id}> الصريحة.
عند إنشاء كائن مهمة جديد محلياً في المتصفح، متى ينبغي استدعاء الدالة crypto.randomUUID()؟
تُستدعى مرة واحدة لحظة إنشاء كائن البيانات نفسه، وليس داخل حلقة الرسم map.
ما القيمة التي تلجأ إليها React افتراضياً بالخفاء عند إغفال تمرير خاصية key لعناصر المصفوفة؟
تعتمد React تلقائياً على فهرس المصفوفة الرقمي مع طباعة تحذير تنبيهي للمطور في سجل المتصفح.