الوحدة 1 · البداية
قواعد JSX الأساسية
17 دقراءة 4 دبيئة تجريب الكود
الدرس في لمحة
اقرأ JSX واكتبه من دون صراع مع المترجم، بمعرفة ما يتحوّل إليه، وكيف تعمل الأقواس المعقوصة، وما قواعد الخصائص والعرض التي تختلف عن HTML.
- 1JSX مجرّد استدعاءات دوال
- 2الأقواس المعقوصة تحمل تعبيرات
- 3الخصائص أسماء JavaScript
- 4أغلق كل وسم
- 5ما الذي يمكن عرضه
لا فيديو هنا، بل الشيء الحقيقي: درس مكتوب وأمثلة قابلة للتشغيل واختبار وتدريب.
يبدو JSX مثل HTML، فيكون أول ما يخطر لك أن تكتب HTML. وهذا ينجح في أغلب الأحيان. ثم تكتب class="card" فيظهر تحذير في الـ console، أو تضع if داخل أقواس معقوصة فتحصل على خطأ ترجمة يشير إلى السطر الخطأ. كل واحدة من هذه المفاجآت تصبح منطقية حين ترى حقيقة JSX.
JSX مجرّد استدعاءات دوال
يترجم Vite كل وسم JSX إلى استدعاء دالة. هذا الـ component:
function MovieCard() {
return <h2 className="title">Arrival</h2>;
}يتحوّل إلى ما يشبه هذا:
import { jsx } from 'react/jsx-runtime';
function MovieCard() {
return jsx('h2', { className: 'title', children: 'Arrival' });
}يُرجع الاستدعاء كائن JavaScript عاديًا اسمه React element: وصف خفيف لما يجب أن يظهر على الشاشة، له type وبعض الـ props. يمكنك تمثيل الفكرة بدالة صغيرة من عندك:
function h(type, props, ...children) {
return { type, props: { ...props, children } };
}
const card = h('article', { className: 'card' },
h('h2', null, 'Arrival'),
h('p', null, 2016),
);
console.log(card.type); // article
console.log(card.props.className); // card
console.log(card.props.children[0].props.children); // ["Arrival"]عناصر React الحقيقية تحمل معلومات أكثر قليلًا، لكن الشكل هو نفسه. تمرّ React على شجرة الكائنات هذه وتُنشئ الـ DOM أو تحدّثه ليطابقها.
لاحظ أن الكود المترجَم يستورد jsx نيابةً عنك. لهذا لا تبدأ ملفات React الحديثة بالسطر import React from 'react'. الدروس القديمة تتضمّن هذا السطر لأن المترجم السابق كان يحوّل JSX إلى استدعاءات React.createElement(…)، التي تحتاج إلى وجود React في النطاق. ومنذ الـ JSX runtime التلقائي في React 17 لم يعد ضروريًا، فاحذفه.
حين تعرف أن JSX استدعاءات دوال، تتوقّف القواعد التالية عن الظهور كأنها اعتباطية.
الأقواس المعقوصة تحمل تعبيرات
داخل JSX، تعيدك { } إلى JavaScript. وكل ما تضعه بداخلها يصبح وسيطًا لاستدعاء دالة، لذا يجب أن يكون تعبيرًا (expression): شيئًا ينتج قيمة.
function MovieCard() {
const movie = { title: 'Arrival', year: 2016, rating: 8 };
const age = 2026 - movie.year;
return (
<article>
<h2>{movie.title.toUpperCase()}</h2>
<p>{movie.year} · {age} years old</p>
<p>{movie.rating >= 8 ? 'Must watch' : 'Maybe'}</p>
</article>
);
}المتغيّرات والوصول إلى الخصائص واستدعاء الدوال والعمليات الحسابية والمعامل الثلاثي a ? b : c كلها تعبيرات. أمّا if وfor وconst فجُمل (statements)، فلا يمكن وضعها داخل الأقواس، تمامًا كما لا يمكنك تمرير if (x) {} وسيطًا لدالة. وحين يكبر المنطق، احسب متغيّرًا فوق return واستخدمه.
هذه هي البطاقة نفسها مع وصف يحتاج إلى تفرّع حقيقي. تعيش جملة if في JavaScript عادية فوق return، ولا يستقبل JSX إلا القيمة النهائية:
function MovieCard({ movie }) {
let label;
if (movie.rating >= 9) {
label = 'Masterpiece';
} else if (movie.rating >= 7) {
label = 'Must watch';
} else {
label = 'Maybe';
}
return <p>{movie.title}: {label}</p>;
}هذا النمط يتوسّع جيدًا. يبقى الـ JSX صورة مقروءة للمخرجات، وتبقى القرارات في كود عادي يمكنك قراءته واختباره وتتبّع أخطائه كأي دالة أخرى. (الـ { movie } في قائمة المعاملات prop؛ ستتعلّم الـ props كما يجب في القسم التالي.)
الخصائص تأخذ أقواسًا معقوصة أيضًا: <img src={movie.poster} alt={movie.title} />. لا تضع الأقواس داخل علامات اقتباس؛ فـ src="{poster}" هو النص الحرفي {poster}.
الخصائص أسماء JavaScript
لأن الـ props تصبح مفاتيح في كائن JavaScript، فهي تتبع قواعد التسمية في JavaScript:
classتصبحclassName، وforتصبحhtmlFor(كلتاهما كلمة محجوزة في JS).- الخصائص المكوّنة من عدّة كلمات تُكتب بصيغة camelCase:
onClickوtabIndexوautoCompleteوmaxLength. - خصائص
aria-*وdata-*تحتفظ بالشَّرطات:aria-label="Remove"وdata-id="42". - تأخذ
styleكائنًا، بخصائص CSS بصيغة camelCase:style={{ marginTop: 8 }}. والرقم المجرّد يعني بكسلات في أغلب الخصائص. والأقواس المزدوجة هي كائن حرفي داخل تعبير JSX.
أغلق كل وسم
JSX أكثر صرامة من HTML. كل عنصر يجب أن يُغلق: <img /> و<input /> و<br />. والـ component يُرجع جذرًا واحدًا، ملفوفًا بـ fragment <>…</> إن احتجت إلى عناصر متجاورة. والتعليقات توضع داخل أقواس معقوصة: {/* like this */}.
ما الذي يمكن عرضه
| ما تضعه بين الأقواس | ما يظهر |
|---|---|
| نص أو رقم | النص نفسه (بما في ذلك 0) |
| عنصر React | ذلك العنصر |
| مصفوفة من العناصر | كل عنصر بالترتيب |
null وundefined وtrue وfalse |
لا شيء |
| كائن عادي | خطأ: «Objects are not valid as a React child» |
صفّ «لا شيء» هو ما يجعل العرض الشرطي ممكنًا، والـ 0 في الصف الأول فخّ شهير ستقابله في درس العرض الشرطي.
صار بإمكانك قراءة أي JSX وتوقّع ما يفعله. في القسم التالي تتوقّف عن كتابة “Arrival” يدويًا، وتتعلّم التفكير بالـ components، فتقسّم شاشة كاملة إلى قطع تستقبل بياناتها عبر الـ props.
أهم النقاط
- يتحوّل JSX إلى استدعاءات دوال تُنشئ كائنات JavaScript عادية تصف الواجهة، ثم تحوّل React هذه الكائنات إلى DOM.
- تضمّ الأقواس المعقوصة أي تعبير JavaScript (قيمة)، لكنها لا تقبل أبدًا جملة مثل
ifأوfor. - الخصائص أسماء JavaScript بصيغة camelCase، لذا تكتب
classNameوhtmlForوonClick، وتمرّر إلىstyleكائنًا. - النصوص والأرقام تُعرض كنص، بينما
nullوundefinedوtrueوfalseلا تعرض شيئًا، والكائنات العادية ترمي خطأ.