React
المكونات في React — دليل شامل Components 2026
📅 2026-10-12⏱ 9 دقائق قراءة
في المقال السابق، كتبت أول تطبيق React واستخدمت JSX والمكونات. الآن سنتعمق في **المكونات (Components)** — وهي **قلب React** وأساس كل تطبيق.
في هذا الدليل العملي، سنأخذك خطوة بخطوة لفهم المكونات، وأنواعها، وكيفية تركيبها، مع تمارين وحلول.
## ما هي المكوّنة (Component)؟
المكوّنة هي **قطعة مستقلة** من واجهة المستخدم، لها منطقها الخاص، ويمكن إعادة استخدامها.
**تشبيه بسيط:** تخيل أن موقعك **سيارة**. المكونات هي **القطع**:
- المحرك (مكوّن).
- العجلات (مكوّن).
- المقود (مكوّن).
- الأبواب (مكوّن).
كل قطعة **مستقلة**، لكنها **تعمل معاً** لتشكيل السيارة.
## لماذا نحتاج المكونات؟
- **إعادة الاستخدام:** اكتب مرة، استخدم في كل مكان.
- **التنظيم:** كود مرتب وسهل الصيانة.
- **الاختبار:** اختبار كل مكوّنة على حدة.
- **التعاون:** فريق العمل يقسّم المهام.
- **الأداء:** React يحدّث فقط المكونات المتغيرة.
## أنواع المكونات
### 1. Function Components (الطريقة الحديثة)
```tsx
function Welcome() {
return <h1>مرحباً!</h1>;
}
export default Welcome;
```
**ميزاتها:**
- ✅ أبسط وأقصر.
- ✅ يمكن استخدام Hooks (`useState`, `useEffect`).
- ✅ الطريقة الموصى بها حالياً.
### 2. Arrow Function Components
```tsx
const Welcome = () => {
return <h1>مرحباً!</h1>;
};
export default Welcome;
```
**أو أقصر:**
```tsx
const Welcome = () => <h1>مرحباً!</h1>;
export default Welcome;
```
### 3. Class Components (الطريقة القديمة)
```tsx
import { Component } from "react";
class Welcome extends Component {
render() {
return <h1>مرحباً!</h1>;
}
}
export default Welcome;
```
**⚠️ تحذير:** **لا تستخدم Class Components** في المشاريع الجديدة. استخدم Function Components.
## إنشاء مكونات
### 1. مكوّنة بسيطة
**أنشئ `src/components/Header.tsx`:**
```tsx
function Header() {
return (
<header className="header">
<h1>موقعي</h1>
<nav>
<a href="/">الرئيسية</a>
<a href="/about">من نحن</a>
</nav>
</header>
);
}
export default Header;
```
### 2. استخدامها في `App.tsx`
```tsx
import Header from "./components/Header";
function App() {
return (
<div>
<Header />
</div>
);
}
export default App;
```
## Props — تمرير البيانات
**Props** هي **بيانات** تُمرر من المكوّن الأب إلى المكوّن الابن.
### 1. Props مع TypeScript
```tsx
interface GreetingProps {
name: string;
age: number;
}
function Greeting({ name, age }: GreetingProps) {
return (
<div>
<h2>مرحباً {name}!</h2>
<p>عمرك {age} سنة</p>
</div>
);
}
export default Greeting;
```
### 2. استخدام Props
```tsx
<Greeting name="أحمد" age={25} />
<Greeting name="محمد" age={30} />
```
**⚠️ ملاحظة:** النصوص `"..."`، الأرقام `{...}`.
### 3. Props مع قيم افتراضية
```tsx
interface ButtonProps {
text?: string;
color?: string;
onClick?: () => void;
}
function Button({
text = "اضغط",
color = "blue",
onClick,
}: ButtonProps) {
return (
<button
onClick={onClick}
style={{ backgroundColor: color, color: "white", padding: "10px 20px", border: "none", borderRadius: "8px", cursor: "pointer" }}
>
{text}
</button>
);
}
```
### 4. تمرير المكونات كـ Children
```tsx
interface CardProps {
title: string;
children: React.ReactNode;
}
function Card({ title, children }: CardProps) {
return (
<div className="card">
<h3>{title}</h3>
<div className="card-body">{children}</div>
</div>
);
}
```
**الاستخدام:**
```tsx
<Card title="معلومات">
<p>هذا محتوى البطاقة</p>
<p>يمكن أن يكون أي شيء</p>
</Card>
```
## تركيب المكونات (Composition)
**التركيب** هو دمج مكونات صغيرة لبناء مكونات أكبر.
### 1. مكونات صغيرة
```tsx
// src/components/Title.tsx
function Title({ children }: { children: React.ReactNode }) {
return <h2 className="title">{children}</h2>;
}
// src/components/Paragraph.tsx
function Paragraph({ children }: { children: React.ReactNode }) {
return <p className="paragraph">{children}</p>;
}
```
### 2. مكوّنة كبيرة تجمعها
```tsx
// src/components/Article.tsx
import Title from "./Title";
import Paragraph from "./Paragraph";
interface ArticleProps {
title: string;
content: string;
}
function Article({ title, content }: ArticleProps) {
return (
<article>
<Title>{title}</Title>
<Paragraph>{content}</Paragraph>
</article>
);
}
```
### 3. استخدام `Article` في `App.tsx`
```tsx
import Article from "./components/Article";
function App() {
return (
<div>
<Article
title="تعلم React"
content="React مكتبة رائعة لبناء واجهات المستخدم."
/>
<Article
title="تعلم TypeScript"
content="TypeScript يضيف أنواع البيانات لـ JavaScript."
/>
</div>
);
}
```
## إنشاء تطبيق "مدونة صغيرة"
دعنا نبني تطبيقاً كاملاً يجمع كل المفاهيم.
### 1. مكوّنة `Post.tsx`
```tsx
interface PostProps {
title: string;
content: string;
author: string;
date: string;
}
function Post({ title, content, author, date }: PostProps) {
return (
<article className="post">
<h2>{title}</h2>
<div className="meta">
<span>✍️ {author}</span>
<span>📅 {date}</span>
</div>
<p>{content}</p>
</article>
);
}
export default Post;
```
### 2. مكوّنة `Blog.tsx`
```tsx
import Post from "./Post";
const posts = [
{
title: "أساسيات React",
content: "React هي مكتبة JavaScript لبناء واجهات المستخدم.",
author: "أحمد",
date: "2026-10-12",
},
{
title: "مقدمة في TypeScript",
content: "TypeScript تضيف أنواع البيانات لـ JavaScript.",
author: "محمد",
date: "2026-10-11",
},
{
title: "بناء تطبيقات Next.js",
content: "Next.js هو إطار عمل مبني على React.",
author: "علي",
date: "2026-10-10",
},
];
function Blog() {
return (
<div className="blog">
<h1>📝 مدونتي</h1>
{posts.map((post) => (
<Post
key={post.title}
title={post.title}
content={post.content}
author={post.author}
date={post.date}
/>
))}
</div>
);
}
export default Blog;
```
### 3. `App.tsx`
```tsx
import Blog from "./components/Blog";
function App() {
return <Blog />;
}
export default App;
```
### 4. تصميم `index.css`
```css
body {
font-family: 'Segoe UI', sans-serif;
background: #f1f5f9;
direction: rtl;
padding: 40px 20px;
}
.blog {
max-width: 800px;
margin: 0 auto;
}
.blog h1 {
color: #1e293b;
margin-bottom: 24px;
text-align: center;
}
.post {
background: white;
padding: 24px;
border-radius: 16px;
box-shadow: 0 2px 8px rgba(0, 0, 0, 0.05);
margin-bottom: 16px;
}
.post h2 {
color: #1e293b;
margin-bottom: 8px;
}
.post .meta {
display: flex;
gap: 16px;
color: #64748b;
font-size: 14px;
margin-bottom: 12px;
}
.post p {
color: #334155;
line-height: 1.7;
}
```
**🎉 مبروك! لديك تطبيق مدونة كامل!**
## الأنماط الشائعة
### 1. مكوّنة في ملف واحد
```
src/components/Button.tsx
```
### 2. عدة مكونات في ملف واحد
```
src/components/Button.tsx (يحتوي على Button, IconButton, ...)
```
### 3. مجلد لكل مكوّنة
```
src/components/Button/
├── Button.tsx
├── Button.css
└── index.ts (لتصدير Button)
```
### 4. تنظيم حسب الميزة
```
src/features/
├── auth/
│ ├── LoginForm.tsx
│ └── RegisterForm.tsx
└── posts/
├── PostList.tsx
└── PostItem.tsx
```
## Props Drilling — المشكلة والحل
**Props Drilling** هو تمرير Props عبر طبقات كثيرة.
**مثال:**
```tsx
// App → Layout → Header → UserMenu → Avatar
<Avatar user={user} /> // يمرر عبر 4 طبقات
```
**⚠️ المشكلة:** كل مكوّنة في الطريق تحتاج تمرير Props.
**✅ الحل:** استخدم **Context API** (سنتعلمه في مقال لاحق).
## PropTypes vs TypeScript
**PropTypes** كانت الطريقة القديمة (JavaScript):
```jsx
import PropTypes from 'prop-types';
function Greeting({ name }) {
return <h1>مرحباً {name}</h1>;
}
Greeting.propTypes = {
name: PropTypes.string.isRequired,
};
```
**TypeScript** هي الطريقة الحديثة:
```tsx
interface GreetingProps {
name: string;
}
function Greeting({ name }: GreetingProps) {
return <h1>مرحباً {name}</h1>;
}
```
**✅ استخدم TypeScript** — أفضل وأنظف.
## أفضل الممارسات
### 1. أسماء المكونات تبدأ بحرف كبير
```tsx
<Button /> // ✅
<button /> // ❌ (عنصر HTML)
```
### 2. مكوّنة واحدة لكل ملف
```
Button.tsx → مكونة Button
Card.tsx → مكونة Card
```
### 3. Props واضحة
```tsx
interface ButtonProps {
text: string;
onClick: () => void;
variant?: "primary" | "secondary";
}
```
### 4. تجنب المكونات الكبيرة جداً
**إذا كان المكوّن أكبر من 200 سطر → قسّمه.**
### 5. استخدم أسماء وصفية
```tsx
✅ <UserProfileCard />
❌ <Card1 />
```
## تمارين عملية
### تمرين 1: مكوّنة Button
أنشئ مكوّنة `Button` تقبل `text` و `onClick`.
**الحل:**
```tsx
interface ButtonProps {
text: string;
onClick: () => void;
}
function Button({ text, onClick }: ButtonProps) {
return (
<button onClick={onClick} className="btn">
{text}
</button>
);
}
```
### تمرين 2: مكوّنة Product
أنشئ مكوّنة `Product` تقبل `name`, `price`, `image`.
**الحل:**
```tsx
interface ProductProps {
name: string;
price: number;
image: string;
}
function Product({ name, price, image }: ProductProps) {
return (
<div className="product">
<img src={image} alt={name} />
<h3>{name}</h3>
<p>{price} $</p>
</div>
);
}
```
### تمرين 3: مكوّنة Alert
أنشئ مكوّنة `Alert` تقبل `type` (success/error/warning) و `message`.
**الحل:**
```tsx
interface AlertProps {
type: "success" | "error" | "warning";
message: string;
}
function Alert({ type, message }: AlertProps) {
const colors = {
success: "#10b981",
error: "#ef4444",
warning: "#f59e0b",
};
return (
<div
style={{
padding: "12px 16px",
borderRadius: "8px",
backgroundColor: colors[type] + "20",
color: colors[type],
border: `2px solid ${colors[type]}`,
}}
>
{message}
</div>
);
}
```
### تمرين 4: مكوّنة Avatar
أنشئ مكوّنة `Avatar` تقبل `name` و `src` اختياري.
**الحل:**
```tsx
interface AvatarProps {
name: string;
src?: string;
}
function Avatar({ name, src }: AvatarProps) {
if (src) {
return <img src={src} alt={name} className="avatar" />;
}
return (
<div className="avatar-fallback">
{name.charAt(0).toUpperCase()}
</div>
);
}
```
### تمرين 5: مكوّنة Card مع Children
أنشئ مكوّنة `Card` تقبل `children` و `title`.
**الحل:**
```tsx
interface CardProps {
title: string;
children: React.ReactNode;
}
function Card({ title, children }: CardProps) {
return (
<div className="card">
<h3>{title}</h3>
<div>{children}</div>
</div>
);
}
```
### تمرين 6: مكوّنة List عامة
أنشئ مكوّنة `List` تقبل مصفوفة `items` ودالة `renderItem`.
**الحل:**
```tsx
interface ListProps<T> {
items: T[];
renderItem: (item: T) => React.ReactNode;
}
function List<T>({ items, renderItem }: ListProps<T>) {
return <ul>{items.map((item, i) => <li key={i}>{renderItem(item)}</li>)}</ul>;
}
// الاستخدام:
<List
items={["أحمد", "محمد"]}
renderItem={(name) => <strong>{name}</strong>}
/>
```
## حل المشاكل الشائعة
### 🔴 المشكلة 1: `Component is not defined`
**السبب:** لم تستورد المكوّنة.
**الحل:**
```tsx
import MyComponent from "./MyComponent";
```
### 🔴 المشكلة 2: `Type 'X' is not assignable to type 'Y'`
**السبب:** Props بنوع خاطئ.
**الحل:** تحقق من الـ interface.
### 🔴 المشكلة 3: المكوّنة لا تظهر
**السبب:** لم تُرجع JSX.
**الحل:**
```tsx
function MyComponent() {
return <div>محتوى</div>; // ← يجب أن يكون هناك return
}
```
### 🔴 المشكلة 4: `key` مفقود في القائمة
**الحل:** أضف `key` فريد.
## جدول مقارنة:
<table>
<thead>
<tr>
<th>النوع</th>
<th>Function</th>
<th>Class</th>
</tr>
</thead>
<tbody>
<tr>
<td><strong>الصيغة</strong></td>
<td><code>function Fn() {}</code></td>
<td><code>class Fn extends Component</code></td>
</tr>
<tr>
<td><strong>State</strong></td>
<td>✅ Hooks</td>
<td>⚠️ this.state</td>
</tr>
<tr>
<td><strong>الحجم</strong></td>
<td>🪶 صغير</td>
<td>📦 كبير</td>
</tr>
<tr>
<td><strong>الحداثة</strong></td>
<td>✅ حديث</td>
<td>⚠️ قديم</td>
</tr>
<tr>
<td><strong>الاستخدام</strong></td>
<td>✅ موصى به</td>
<td>❌ تجنبه</td>
</tr>
</tbody>
</table>
## قائمة تحقق نهائية
<table>
<thead>
<tr>
<th>المهمة</th>
<th>الحالة</th>
</tr>
</thead>
<tbody>
<tr>
<td>فهم أنواع المكونات</td>
<td>⬜</td>
</tr>
<tr>
<td>إنشاء مكونات بسيطة</td>
<td>⬜</td>
</tr>
<tr>
<td>استخدام Props</td>
<td>⬜</td>
</tr>
<tr>
<td>تمرير Children</td>
<td>⬜</td>
</tr>
<tr>
<td>تركيب المكونات</td>
<td>⬜</td>
</tr>
<tr>
<td>بناء تطبيق المدونة</td>
<td>⬜</td>
</tr>
<tr>
<td>حل التمارين الستة</td>
<td>⬜</td>
</tr>
</tbody>
</table>
## ماذا بعد هذا المقال؟
الآن بعد أن أتقنت المكونات، أنت جاهز للمقال التالي:
1. **State** — إدارة البيانات المتغيرة.
2. **الأحداث** — التعامل مع تفاعل المستخدم.
3. **useEffect** — التأثيرات الجانبية.
## الخلاصة
في هذا المقال، تعلمت:
- ✅ ما هي المكونات ولماذا نحتاجها.
- ✅ أنواع المكونات (Function, Class).
- ✅ Props وكيفية تمريرها.
- ✅ Children وتركيب المكونات.
- ✅ أفضل ممارسات تنظيم المكونات.
- ✅ Props Drilling ومشكلته.
- ✅ حل 6 تمارين عملية.
**تذكر:** المكونات هي أساس React. أتقنها جيداً، وستتمكن من بناء أي تطبيق.
**هل أتقنت المكونات؟ شاركنا في التعليقات!**