الوحدة 1 · البداية
أول component لك
18 دقراءة 4 دبيئة تجريب الكود
الدرس في لمحة
اكتب components في React على شكل دوال عادية، وضع بعضها داخل بعض، وقسّمها إلى ملفات باستخدام import وexport، وتجنّب أخطاء التسمية والتداخل التي تكسرها.
- 1الـ component مجرّد دالة
- 2components داخل components
- 3component واحد لكل ملف
- 4الـ components يجب أن تكون متوقَّعة
- 5أرجِع جذرًا واحدًا
لا فيديو هنا، بل الشيء الحقيقي: درس مكتوب وأمثلة قابلة للتشغيل واختبار وتدريب.
حاليًا يحتوي App.jsx على عنوان واحد. أمّا شاشة Watchlist الحقيقية ففيها ترويسة ونموذج وشريط فلترة وقائمة من بطاقات الأفلام، وبعض القطع تتكرّر مرات كثيرة. إن كتبت كل ذلك في دالة واحدة فستحصل على component من 300 سطر لا يرغب أحد في لمسه. الـ components تتيح لك أن تسمّي كل قطعة، وتكتبها مرة واحدة، وتعيد استخدامها.
الـ component مجرّد دالة
هذا component كامل:
function Header() {
return (
<header>
<h1>My Watchlist</h1>
<p>Movies I want to see</p>
</header>
);
}
export default function App() {
return (
<main>
<Header />
</main>
);
}ثلاث قواعد تجعل هذا يعمل:
- إنه دالة تُرجع JSX. الـ JSX هو الصياغة الشبيهة بـ HTML داخل
return. ستتعلّم قواعده في الدرس التالي. - اسمه يبدأ بحرف كبير. الوسم
<Header />يقول لـ React «استدعِ الدالة Header». أمّا<header>بالحرف الصغير فيعني عنصر HTML. - تستخدمه كوسم، لا كاستدعاء دالة. تكتب
<Header />وReact تقرّر متى تستدعيHeader(). وهذا ما يتيح لـ React أن تتتبّعه وتعيد رسمه (re-render) وتمنحه state لاحقًا.
الأقواس حول الـ JSX متعدّد الأسطر ليست شرطًا من React. وظيفتها منع JavaScript من إدراج فاصلة منقوطة تلقائيًا تُنهي return مبكرًا، فتُرجع undefined بصمت.
components داخل components
تتداخل الـ components كما يتداخل HTML. أضف بطاقة فيلم واستخدمها مرتين:
function MovieCard() {
return (
<article>
<h2>Arrival</h2>
<p>2016</p>
</article>
);
}
export default function App() {
return (
<main>
<Header />
<MovieCard />
<MovieCard />
</main>
);
}لديك الآن بطاقتان متطابقتان. واضح أن هذا ليس مفيدًا بعد؛ يجب أن تعرض البطاقات أفلامًا مختلفة. تمرير البيانات إلى الـ component هو وظيفة الـ props، وستصل إليها في القسم 2. الآن لاحظ الشكل فقط: App هو الأب، وHeader والبطاقتان MovieCard أبناؤه. كل تطبيق React شجرة من هذا النوع.
component واحد لكل ملف
عندما يُعاد استخدام component أو يكبر حتى يتجاوز شاشة واحدة، امنحه ملفًا خاصًا به. الترتيب المعتاد هو مجلد src/components:
export default function MovieCard() {
return (
<article>
<h2>Arrival</h2>
<p>2016</p>
</article>
);
}import Header from './components/Header.jsx';
import MovieCard from './components/MovieCard.jsx';
export default function App() {
return (
<main>
<Header />
<MovieCard />
</main>
);
}تمنحك JavaScript modules نوعين من التصدير:
- التصدير الافتراضي (default export):
export default function MovieCard(). واحد لكل ملف، ويُستورد بلا أقواس:import MovieCard from '…'. - التصدير المُسمّى (named export):
export function MovieCard(). أي عدد في الملف، ويُستورد بأقواس:import { MovieCard } from '…'.
كلاهما جيد. كثير من الفرق تفضّل الـ named exports لأن الاسم ثابت، والمحرّرات تعيد تسميته في كل مكان نيابةً عنك. اختر أسلوبًا واحدًا لكل مشروع والتزم به. تستخدم هذه الدورة الـ default exports للـ components، تماشيًا مع الملف الذي أنشأه Vite.
الـ components يجب أن تكون متوقَّعة
قد تستدعي React دالة الـ component مرات كثيرة: مع كل تحديث، ومرتين تحت StrictMode، وأحيانًا حين تجهّز شاشة في الخلفية. لذلك يجب أن يتصرّف الـ component كالمعادلة الرياضية: مع المدخلات نفسها يُرجع الـ JSX نفسه، ولا يغيّر شيئًا خارجه أثناء الرسم. لا تعدّل متغيّرات عامة، ولا تجلب بيانات، ولا تلمس الـ DOM مباشرة داخل جسم الدالة. ستتعلّم أين يوضع هذا النوع من العمل (الـ event handlers والـ effects) في القسم 3.
إليك الفرق عمليًا. الـ component الذي ينفّذ visits += 1 على متغيّر في مستوى الـ module سيعطي أرقامًا مختلفة في التطوير والإنتاج، لأن StrictMode يستدعيه مرتين. أمّا الـ component الذي يكتفي بقراءة مدخلاته وإرجاع JSX فيعطي الجواب نفسه مهما استدعته React.
أرجِع جذرًا واحدًا
يُرجع الـ component عنصر JSX واحدًا. لإرجاع عناصر متجاورة من دون إضافة <div> زائد، غلّفها بـ fragment:
export default function App() {
return (
<>
<Header />
<MovieCard />
</>
);
}الـ fragment يجمع العناصر في كودك لكنه لا يضيف شيئًا إلى الـ DOM. استخدم عنصرًا حقيقيًا مثل <main> أو <section> حين يكون له معنى في بنية الصفحة، واستخدم الـ fragment حين لا يكون.
صار بإمكانك تقسيم الشاشة إلى قطع مسمّاة. في الدرس التالي تتعلّم قواعد JSX نفسه: لماذا نكتب className لا class، وكيف تعمل الأقواس المعقوصة، وإلى ماذا يتحوّل JSX حين يترجمه Vite.
أهم النقاط
- الـ component دالة JavaScript يبدأ اسمها بحرف كبير وتُرجع JSX.
- تستخدم الـ component كأنه وسم HTML، مثل
<MovieCard />، وReact تستدعي الدالة نيابةً عنك. - امنح كل component قابل لإعادة الاستخدام ملفًا خاصًا به وصدّره، ثم استورده حيثما تحتاجه.
- عرّف الـ components في المستوى الأعلى من الـ module، ولا تعرّفها أبدًا داخل component آخر.