🎯 ما ستتعلمه في هذا الدرس
- فهم أنواع Components ومتى تستخدم كل نوع
- تمرير البيانات بين المكونات باستخدام Props بشكل احترافي
- استخدام Composition لبناء تطبيقات معقدة من مكونات بسيطة
- استخدام Children لإنشاء مكونات قابلة للتخصيص
- تجنب الأخطاء الشائعة التي يقع فيها 90% من المبتدئين
🧩 ما هو Component ولماذا يُعتبر "السر" وراء React؟
Component (المكون) هو قطعة مستقلة وقابلة لإعادة الاستخدام من واجهة المستخدم. يمكن أن يكون زر، نموذج، قائمة، أو أي عنصر واجهة مستخدم آخر. لكن لماذا هذا المفهوم مهم جداً؟
في بداية تعلمي للبرمجة، كنت أبني موقع متجر إلكتروني باستخدام HTML وCSS وJavaScript العادي. المشكلة؟ كل صفحة كانت ملفاً منفصلاً، وكل زر "أضف للسلة" كان يتكرر في 20 مكاناً مختلفاً. عندما أردت تغيير لون الزر، اضطررت لتعديل 20 ملفاً! استغرقت 3 ساعات لتعديل شيء بسيط.
مع React، تكتب مكون Button مرة واحدة، وتستخدمه في 100 مكان. تغيير لون الزر؟ تعديل في ملف واحد فقط — والتغيير ينطبق على كل مكان. هذا هو قوة المكونات.
فوائد المكونات في المشاريع الحقيقية:
- إعادة الاستخدام: مكون Button واحد يستخدم في 50 مكاناً مختلفاً
- سهولة الصيانة: تعديل في مكان واحد ينطبق على كل مكان
- اختبار أسهل: تختبر كل مكون بمعزل عن الآخرين
- تقسيم العمل: فريق من 5 مطورين يعمل على مكونات مختلفة بدون تضارب
- كود أنظف: كل ملف 100-200 سطر بدلاً من ملف واحد 2000 سطر
📝 أنواع Components — Function vs Class
1. Function Component (الحديث والمستحسن — 95% من المشاريع الجديدة)
Function Component هو ببساطة دالة JavaScript تُرجع JSX. هذا هو النمط الحديث والموصى به من Facebook (Meta) منذ 2019. السبب؟ أبسط، أخف، ويدعم Hooks بشكل كامل.
function Greeting(props) {
return <h1>مرحباً {props.name}!</h1>;
}
function GreetingBetter({ name, age }) {
return (
<div className="greeting-card">
<h1>مرحباً {name}!</h1>
<p>عمرك: {age} سنة</p>
</div>
);
}
<Greeting name="أحمد" />
<GreetingBetter name="فاطمة" age={25} />
💡 نصيحة من الخبرة: استخدم دائماً Destructuring في Props. بدلاً من props.name و props.age، استخدم { name, age }. هذا يجعل الكود أقصر وأسهل للقراءة — خاصة عندما يكون لديك 10+ Props.
2. Class Component (القديم — تعرفه فقط للصيانة)
Class Components كانت الطريقة الوحيدة لإدارة State قبل 2019. لا تُنصح بها للمشاريع الجديدة، لكنك قد تصادفها في مشاريع قديمة تحتاج صيانة.
import React, { Component } from 'react';
class Greeting extends Component {
render() {
return <h1>مرحباً {this.props.name}!</h1>;
}
}
⚠️ خطأ شائع: بعض المبتدئين يتعلمون Class Components أولاً لأنها تظهر في دورات قديمة. هذا خطأ! ابدأ بـ Function Components مباشرة — كل المشاريع الحديثة تستخدمها.
🎨 Props — نقل البيانات بين المكونات بشكل احترافي
Props (اختصار Properties) هي بيانات تُمرر من مكون أب (Parent) لمكون ابن (Child). تشبه معاملات الدالة في JavaScript. لكن هناك قاعدة ذهبية: Props قراءة فقط (Read-only).
لماذا Props ثابتة؟ لأن React تبني على مفهوم "One-way Data Flow" (تدفق بيانات باتجاه واحد). البيانات تتدفق من الأعلى للأسفل، مثل شلال. هذا يجعل تتبع الأخطاء سهلاً — إذا ظهرت بيانات خاطئة، تعرف مصدرها مباشرة من المكون الأب.
مثال واقعي: بطاقة مستخدم في تطبيق تواصل اجتماعي
function UserCard({ name, age, email, isActive, avatar, onMessage }) {
return (
<div className={`user-card ${isActive ? 'active' : 'inactive'}`}>
<img
src={avatar}
alt={`صورة ${name}`}
className="avatar"
/>
<div className="user-info">
<h3>{name}</h3>
<p>العمر: {age} سنة</p>
<p>البريد: {email}</p>
<span className={`status-badge ${isActive ? 'online' : 'offline'}`}>
{isActive ? '🟢 نشط الآن' : '🔴 غير نشط'}
</span>
</div>
<button onClick={onMessage} className="msg-btn">
💬 رسالة
</button>
</div>
);
}
<UserCard
name="أحمد محمد"
age={28}
email="ahmed@example.com"
isActive={true}
avatar="https://example.com/ahmed.jpg"
onMessage={() => alert('فتح دردشة مع أحمد')}
/>
<UserCard
name="فاطمة علي"
age={24}
email="fatima@example.com"
isActive={false}
avatar="https://example.com/fatima.jpg"
onMessage={() => alert('فتح دردشة مع فاطمة')}
/>
💡 نصيحة احترافية: عند تمرير دوال (Functions) كـ Props، استخدم دائماً onSomething كاسم — مثل onClick، onMessage، onDelete. هذا يجعل الكود أكثر وضوحاً ويتبع اتفاقية React القياسية.
🎯 Composition — بناء تطبيقات معقدة من مكونات بسيطة
Composition (التركيب) هو المفهوم الأساسي في React: بناء واجهات معقدة من مكونات بسيطة صغيرة. تخيل بناء منزل — لا تبدأ بمنزل كامل، بل تبدأ بلبنات (طوب، أبواب، نوافذ) ثم تركبها معاً.
في مشروع حقيقي عملته (لوحة تحكم لمتجر إلكتروني)، قسمت الواجهة إلى 12 مكوناً:
- Sidebar (القائمة الجانبية)
- Header (الشريط العلوي)
- StatsCard (بطاقة إحصائيات — استخدمتها 4 مرات)
- Chart (رسم بياني)
- ProductTable (جدول المنتجات)
- OrderList (قائمة الطلبات)
النتيجة؟ كل مكون 80-150 سطر، سهل الفهم والتعديل. لو أردت تغيير تصميم StatsCard، عدلت ملف واحد — والتغيير انطبق على 4 أماكن.
مثال: هيكل تطبيق كامل
function App() {
return (
<div className="app-container">
<Header
title="لوحة التحكم"
user={currentUser}
/>
<div className="main-layout">
<Sidebar activeItem="dashboard" />
<main className="content">
<StatsRow />
<div className="charts-grid">
<SalesChart period="month" />
<UsersChart period="week" />
</div>
<RecentOrders limit={5} />
</main>
</div>
<Footer version="2.1.0" />
</div>
);
}
function Header({ title, user }) {
return (
<header className="app-header">
<h1>{title}</h1>
<div className="user-menu">
<img src={user.avatar} alt={user.name} />
<span>{user.name}</span>
</div>
</header>
);
}
function Sidebar({ activeItem }) {
const items = [
{ id: 'dashboard', label: 'الرئيسية', icon: '🏠' },
{ id: 'products', label: 'المنتجات', icon: '📦' },
{ id: 'orders', label: 'الطلبات', icon: '🛒' },
{ id: 'users', label: 'المستخدمين', icon: '👥' },
];
return (
<aside className="sidebar">
{items.map(item => (
<a
key={item.id}
href={`#${item.id}`}
className={activeItem === item.id ? 'active' : ''}
>
{item.icon} {item.label}
</a>
))}
</aside>
);
}
⚡ Children — إنشاء مكونات قابلة للتخصيص
Children هي خاصية خاصة في React. أي محتوى تضعه بين وسمي المكون (<Card>...</Card>) يصبح props.children. هذا يسمح بإنشاء "مكونات غلاف" (Wrapper Components) قابلة لإعادة الاستخدام مع محتوى مختلف.
من تجربتي: في مشروع لوحة تحكم، احتجت بطاقات (Cards) بتصاميم مختلفة — بطاقة إحصائيات، بطاقة رسوم بيانية، بطاقة تنبيهات. بدلاً من إنشاء 3 مكونات منفصلة، أنشأت مكون Card واحداً يستخدم Children:
function Card({ children, title, variant = 'default', footer }) {
return (
<div className={`card card-${variant}`}>
{title && (
<div className="card-header">
<h3>{title}</h3>
</div>
)}
<div className="card-body">
{children}
</div>
{footer && (
<div className="card-footer">
{footer}
</div>
)}
</div>
);
}
<Card title="إجمالي المبيعات" variant="stats">
<div className="stat-value">₤ 125,000</div>
<div className="stat-change positive">+12% عن الشهر الماضي</div>
</Card>
<Card title="مبيعات الشهر" variant="chart">
<BarChart data={salesData} />
</Card>
<Card
title="تنبيه"
variant="alert"
footer={<button>فهمت</button>}
>
<p>هناك 5 طلبات بحاجة للمراجعة العاجلة.</p>
</Card>
🎯 نصيحة احترافية: استخدم variant لتغيير التصميم بدون تغيير المنطق. هذا يجعل مكون Card مرناً جداً — يمكن استخدامه في 10 سياقات مختلفة بنفس الكود الأساسي.
💡 أفضل الممارسات من مشاريع حقيقية
1. اسم المكون يبدأ بحرف كبير
React تفرّق بين المكونات (Component) وعناصر HTML العادية عن طريق الحرف الأول. <Button> = مكون React. <button> = عنصر HTML.
2. مكون واحد = ملف واحد
ضع كل مكون في ملف منفصل. هيكل المشروع النظيف:
src/
components/
Button/
Button.js
Button.css
Card/
Card.js
Card.css
pages/
Home/
Home.js
Dashboard/
Dashboard.js
3. تجنب Props Drilling (الحفر العميق)
Props Drilling هو تمرير Props عبر 5-6 مستويات من المكونات. الحل: Context API أو Redux (سنتعلمها لاحقاً).
<App user={user}>
<Dashboard user={user}>
<Sidebar user={user}>
<UserMenu user={user}>
<Avatar user={user} />
</UserMenu>
</Sidebar>
</Dashboard>
</App>
4. استخدم defaultProps للقيم الافتراضية
function Button({
label,
variant = 'primary',
size = 'medium',
disabled = false,
onClick
}) {
return (
<button
className={`btn btn-${variant} btn-${size}`}
disabled={disabled}
onClick={onClick}
>
{label}
</button>
);
}
<Button label="حفظ" onClick={handleSave} />
<Button
label="حذف"
variant="danger"
size="small"
onClick={handleDelete}
/>
🚀 تمرين عملي: بناء لوحة تحكم مصغرة
قبل الانتقال للدرس التالي، جرب بناء هذا التطبيق الصغير:
📝 تلميح: ابدأ بـ App.js، ثم أنشئ كل مكون في ملف منفصل. استخدم Destructuring في Props. لا تنسَ خاصية key في الحلقات (map). شارك الكود على واتساب 01229068356 وسنراجعه معك!
📚 الخلاصة والخطوات التالية
في هذا الدرس تعلمت:
- ✅ Function Components هي الطريقة الحديثة (Class Components للصيانة فقط)
- ✅ Props تمرر بيانات من الأب للابن — ثابتة (Read-only)
- ✅ Composition يسمح ببناء تطبيقات معقدة من مكونات بسيطة
- ✅ Children تُنشئ مكونات غلاف قابلة للتخصيص
- ✅ Destructuring وdefaultProps يجعلان الكود أنظف
- ✅ تجنب Props Drilling باستخدام Context API (قادم)
الدرس القادم: سنتعلم Hooks (useState, useEffect) — السر وراء جعل Function Components تفاعلية. سنبني عداد، نافذة منبثقة (Modal)، وقائمة مهام تفاعلية!
🎯 مهمة قبل الدرس القادم: أكمل تمرين Dashboard الصغير. جرب إضافة مكون جديد (مثل NotificationBadge) واستخدمه داخل Header. كلما تمرّنت أكثر، أسرع ستتعلم!