Menu
flag Ar iconالعربيةdown icon

مكوّنات React: مكوّنات الدوال مع أمثلة

مكوّن React دالة JavaScript تُرجع JSX. تعلّم كيف تكتب مكوّنات الدوال وتسمّيها، وتركّبها في شجرة، وتوزعها على ملفات، وتبقيها نقية، وكيف تختلف المكوّنات عن العناصر.

تحتوي هذه الصفحة على محررات قابلة للتشغيل - حرّر، شغّل، وشاهد النتيجة فوراً.

مكوّن React دالة JavaScript تُرجع JSX: قطعة واجهة قابلة لإعادة الاستخدام مثل زر أو بطاقة أو صفحة كاملة. تستخدمه مثل وسم HTML، <Profile />، وتستدعي React الدالة لتعرف ما تضعه على الشاشة. تُبنى التطبيقات بوضع مكوّنات داخل مكوّنات أخرى.

يعرض App المكوّن Profile مرتين، وكل Profile يعرض Avatar. غيّر الأحرف الأولى داخل Avatar فيتحدث الملفان الشخصيان كلاهما، لأنهما يتشاركان تعريفًا واحدًا. كل شخص في هذه القائمة هو نفسه حاليًا؛ وتُظهر الصفحة التالية، props، كيف تمرر لكل نسخة بياناتها الخاصة.

كتابة مكوّن

لمكوّن الدالة شرطان:

  1. يبدأ اسمه بحرف كبير: Profile، لا profile.
  2. يُرجع شيئًا يمكن لـ React عرضه: JSX، أو نصًا، أو رقمًا، أو null (لا يعرض شيئًا)، أو مصفوفة منها.
function Welcome() {
    return <h1>Welcome back</h1>;
}

// Arrow functions work the same way
const Welcome = () => <h1>Welcome back</h1>;

عندما تمتد JSX على عدة أسطر، ضعها بين قوسين بعد return. من دونهما، فإن return المتبوعة بسطر جديد تُرجع undefined، ويُتجاهل كل ما بعدها.

لماذا يجب أن يبدأ الاسم بحرف كبير

تنظر JSX إلى الحرف الأول من الوسم. الحرف الصغير يعني عنصر HTML مدمجًا، فيبقى <div> هو <div>. والحرف الكبير يعني «متغيرًا في النطاق»، فيستدعي <Profile /> دالتك Profile. إذا سمّيت مكوّنًا بحرف صغير فستنشئ React بدلًا منه عنصر HTML غير معروف بهذا الاسم:

لا يعرض السطر الثاني إلا تسميته، ولا تعرض وحدة التحكم إلا Greeting ran. وضعت React وسم <greeting> فارغًا في الصفحة ولم تستدعِ الدالة ذات الاسم بالحرف الصغير أبدًا. ويحذّر بناء التطوير أيضًا بأن The tag <greeting> is unrecognized in this browser؛ أما المعاينة فتعمل مثل بناء الإنتاج، فلا ترى إلا النص المفقود. أعد تسمية الدالة إلى Greetings والوسم إلى <Greetings /> لإصلاح ذلك.

تركيب المكوّنات

صُممت المكوّنات لتتداخل. الصفحة شجرة: App في الأعلى، ثم أجزاء التخطيط، ثم أجزاء أصغر وصولًا إلى أزرار مفردة. كل مكوّن لا يعرف إلا القطع التي يعرضها مباشرة، فيمكنك التفكير في واحد منها في كل مرة.

لكل LikeButton حالته الخاصة، فالإعجاب بمنشور واحد لا يمس المنشورات الأخرى. ولإضافة زر مشاركة إلى كل منشور، تكتبه مرة واحدة وتضيف <ShareButton /> داخل Post.

متى تقسّم مكوّنًا

لا توجد قاعدة ثابتة، لكن بعض العلامات تقول إن قطعة ما تستحق مكوّنًا خاصًا بها: الترميز نفسه يظهر في موضعين، أو جزء من JSX له حالته الخاصة (مثل زر الإعجاب أعلاه)، أو طالت الدالة حتى صرت تمرر الشاشة لترى return. التقسيم وفق هذه العلامات يُبقي كل مكوّن صغيرًا بما يكفي لقراءته في شاشة واحدة. والتقسيم المبكر لا يكلّف الكثير: المكوّن مجرد دالة، فدمج اثنين من جديد سهل.

تصدير المكوّنات واستيرادها

تحتوي المحررات هنا على ملف واحد، لكن المشروع الحقيقي يضع المكوّنات في ملفاتها الخاصة. يمكن للملف أن يحتوي على تصدير افتراضي واحد وأي عدد من التصديرات المسماة:

// Avatar.jsx
export default function Avatar({ initials }) {
    return <div className="avatar">{initials}</div>;
}

// Badge.jsx
export function Badge({ label }) {
    return <span className="badge">{label}</span>;
}
export function NewBadge() {
    return <Badge label="new" />;
}
// Profile.jsx
import Avatar from './Avatar.jsx';
import { Badge, NewBadge } from './Badge.jsx';

export default function Profile() {
    return (
        <div>
            <Avatar initials="AL" />
            <Badge label="admin" />
            <NewBadge />
        </div>
    );
}

يمكن استيراد التصدير الافتراضي بأي اسم؛ أما التصدير المسمى فيُستورد بين أقواس معقوصة باسمه الدقيق. تختار الفرق عادة أسلوبًا واحدًا وتلتزم به. وكثيرًا ما تطابق أسماء الملفات اسم المكوّن: Avatar.jsx يصدّر Avatar.

أبقِ المكوّنات نقية

تتوقع React أن يتصرف المكوّن كدالة نقية أثناء العرض: الـ props والحالة نفسها تعطيان JSX نفسها، والعرض لا يغيّر شيئًا كان موجودًا قبل تشغيله. قد تعرض React مكوّنًا مرات عديدة، في أوقات لا تتحكم فيها، فالمكوّن الذي يعدّل متغيرات خارجية أثناء العرض ينتج مخرجات مختلفة في كل مرة.

تبدأ الأكواب غير النقية بالأرقام 1 و2 و3. انقر الزر: لم يتغير شيء في الضيوف، ومع ذلك تقرأ القائمة غير النقية الآن 4 و5 و6، لأن كل عرض أضاف إلى المتغير المشترك guest. أما الأكواب النقية فتأخذ رقمها من props وتبقى صحيحة. في التطوير، يعرض Strict Mode كل مكوّن مرتين ليكشف هذا النوع من الأخطاء بالضبط؛ والمعاينة تعمل مثل بناء الإنتاج، فلا يظهر الانحراف هنا إلا عندما تعيد العرض.

تغيير الأشياء لا بأس به، لكن ليس أثناء العرض. حدّث الحالة في معالجات الأحداث، وتعامل مع العالم الخارجي (المؤقتات والاشتراكات وعنوان المستند) في التأثيرات.

المكوّنات مقابل العناصر

المكوّن هو الدالة، Profile. والعنصر هو ما تنشئه JSX عندما تكتب <Profile />: كائن صغير يقول «اعرض Profile بهذه الـ props». تنشئ React العناصر، وتستدعي المكوّنات التي تسميها، وتحوّل النتيجة إلى DOM. لا تستدعي مكوّنًا بنفسك على شكل Profile() أبدًا؛ بل تكتب <Profile /> وتترك React تستدعيه، لتتمكن من تتبع حالته وموضعه في الشجرة.

هذا الموضع مهم. يعرّف هذا المثال مكوّنًا داخل مكوّن آخر، وهو خطأ شائع:

اكتب شيئًا، ثم انقر الزر: يختفي نصك. كل عرض لـ App ينشئ دالة NameField جديدة تمامًا، فترى React نوع مكوّن مختلفًا في ذلك الموضع وتتخلص من القديم مع حالته. انقل NameField إلى ما قبل App، في المستوى الأعلى من الملف، فيبقى النص بعد كل نقرة. تشرح صفحة العرض كيف تقرر React ما تحتفظ به.

مكوّنات الدوال ومكوّنات الأصناف

قبل وصول الخطافات في React 16.8، كانت المكوّنات التي تحتاج إلى حالة تُكتب كأصناف:

import { Component } from 'react';

class Welcome extends Component {
    render() {
        return <h1>Hello, {this.props.name}</h1>;
    }
}

ما زالت مكوّنات الأصناف تعمل في React 19، وستصادفها في المشاريع القديمة وفي حدود الأخطاء، التي ما زالت تتطلب صنفًا. أما الكود الجديد فيستخدم مكوّنات الدوال مع خطافات مثل useState وuseEffect، التي تؤدي المهام نفسها بكود أقل. تربط صفحة مكوّنات الأصناف كل ميزة من ميزات الأصناف بالخطاف المقابل لها.

الأسئلة الشائعة

ما هو المكوّن في React؟

المكوّن قطعة واجهة قابلة لإعادة الاستخدام تُكتب كدالة JavaScript تُرجع JSX. تستخدمه مثل وسم HTML، <Profile />، وتستدعي React الدالة لتعرف ما الذي ترسمه.

لماذا يجب أن تبدأ أسماء مكوّنات React بحرف كبير؟

تعتمد JSX على الحرف الأول لتحدد نوع الوسم. الوسم بحرف صغير مثل <profile /> يُعامل كعنصر HTML اسمه profile، ولا تُستدعى دالتك أبدًا. أما الوسم بحرف كبير مثل <Profile /> فيشير إلى مكوّنك.

ما الفرق بين مكوّنات الدوال ومكوّنات الأصناف؟

كلاهما يصف الواجهة. مكوّنات الدوال دوال عادية وتستخدم الخطافات للحالة والتأثيرات؛ ومكوّنات الأصناف ترث React.Component وتستخدم توابع مثل render وcomponentDidMount. الكود الجديد يستخدم مكوّنات الدوال.

ما هو المكوّن النقي في React؟

المكوّن النقي يُرجع JSX نفسها للـ props والحالة نفسيهما، ولا يغيّر شيئًا خارجه أثناء العرض. تعتمد React على ذلك لتعرض المكوّنات بقدر ما تحتاج دون مفاجآت.

هل يمكنني تعريف مكوّن داخل مكوّن آخر؟

تجنّب ذلك. المكوّن المعرَّف داخل مكوّن آخر دالة جديدة في كل عرض، فتعامله React كمكوّن مختلف في كل مرة وتعيد ضبط حالته. عرّف المكوّنات في المستوى الأعلى من الملف.

رسم توضيحي للغات البرمجة في Coddy

تعلّم البرمجة مع Coddy

ابدأ الآن