React📅 2026-10-12⏱ 9 دقائق قراءة⚛️ مقال 3 من 10

المكونات في React — دليل شامل Components 2026

دليل عملي مفصل للمكونات في React — الأنواع، Props، التركيب، إعادة الاستخدام، مع تمارين وحلول

في المقال السابق، كتبت أول تطبيق React واستخدمت JSX والمكونات. الآن سنتعمق في المكونات (Components) — وهي قلب React وأساس كل تطبيق.

في هذا الدليل العملي، سنأخذك خطوة بخطوة لفهم المكونات، وأنواعها، وكيفية تركيبها، مع تمارين وحلول.

ما هي المكوّنة (Component)؟

المكوّنة هي قطعة مستقلة من واجهة المستخدم، لها منطقها الخاص، ويمكن إعادة استخدامها.

تشبيه بسيط: تخيل أن موقعك سيارة. المكونات هي القطع:

  • المحرك (مكوّن).
  • العجلات (مكوّن).
  • المقود (مكوّن).
  • الأبواب (مكوّن).

كل قطعة مستقلة، لكنها تعمل معاً لتشكيل السيارة.

لماذا نحتاج المكونات؟

  • إعادة الاستخدام: اكتب مرة، استخدم في كل مكان.
  • التنظيم: كود مرتب وسهل الصيانة.
  • الاختبار: اختبار كل مكوّنة على حدة.
  • التعاون: فريق العمل يقسّم المهام.
  • الأداء: React يحدّث فقط المكونات المتغيرة.

أنواع المكونات

1. Function Components (الطريقة الحديثة)

function Welcome() {
  return <h1>مرحباً!</h1>;
}

export default Welcome;

ميزاتها:

  • ✅ أبسط وأقصر.
  • ✅ يمكن استخدام Hooks (useState, useEffect).
  • ✅ الطريقة الموصى بها حالياً.

2. Arrow Function Components

const Welcome = () => {
  return <h1>مرحباً!</h1>;
};

export default Welcome;

أو أقصر:

const Welcome = () => <h1>مرحباً!</h1>;

export default Welcome;

3. Class Components (الطريقة القديمة)

import { Component } from "react";

class Welcome extends Component {
  render() {
    return <h1>مرحباً!</h1>;
  }
}

export default Welcome;

⚠️ تحذير: لا تستخدم Class Components في المشاريع الجديدة. استخدم Function Components.

إنشاء مكونات

1. مكوّنة بسيطة

أنشئ src/components/Header.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

import Header from "./components/Header";

function App() {
  return (
    <div>
      <Header />
    </div>
  );
}

export default App;

Props — تمرير البيانات

Props هي بيانات تُمرر من المكوّن الأب إلى المكوّن الابن.

1. Props مع TypeScript

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

<Greeting name="أحمد" age={25} />
<Greeting name="محمد" age={30} />

⚠️ ملاحظة: النصوص "..."، الأرقام {...}.

3. Props مع قيم افتراضية

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

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>
  );
}

الاستخدام:

<Card title="معلومات">
  <p>هذا محتوى البطاقة</p>
  <p>يمكن أن يكون أي شيء</p>
</Card>

تركيب المكونات (Composition)

التركيب هو دمج مكونات صغيرة لبناء مكونات أكبر.

1. مكونات صغيرة

// 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. مكوّنة كبيرة تجمعها

// 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

import Article from "./components/Article";

function App() {
  return (
    <div>
      <Article
        title="تعلم React"
        content="React مكتبة رائعة لبناء واجهات المستخدم."
      />
      <Article
        title="تعلم TypeScript"
        content="TypeScript يضيف أنواع البيانات لـ JavaScript."
      />
    </div>
  );
}

إنشاء تطبيق "مدونة صغيرة"

دعنا نبني تطبيقاً كاملاً يجمع كل المفاهيم.

1. مكوّنة Post.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

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

import Blog from "./components/Blog";

function App() {
  return <Blog />;
}

export default App;

4. تصميم index.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 عبر طبقات كثيرة.

مثال:

// App → Layout → Header → UserMenu → Avatar
<Avatar user={user} />  // يمرر عبر 4 طبقات

⚠️ المشكلة: كل مكوّنة في الطريق تحتاج تمرير Props.

✅ الحل: استخدم Context API (سنتعلمه في مقال لاحق).

PropTypes vs TypeScript

PropTypes كانت الطريقة القديمة (JavaScript):

import PropTypes from 'prop-types';

function Greeting({ name }) {
  return <h1>مرحباً {name}</h1>;
}

Greeting.propTypes = {
  name: PropTypes.string.isRequired,
};

TypeScript هي الطريقة الحديثة:

interface GreetingProps {
  name: string;
}

function Greeting({ name }: GreetingProps) {
  return <h1>مرحباً {name}</h1>;
}

✅ استخدم TypeScript — أفضل وأنظف.

أفضل الممارسات

1. أسماء المكونات تبدأ بحرف كبير

<Button />  // ✅
<button />  // ❌ (عنصر HTML)

2. مكوّنة واحدة لكل ملف

Button.tsx      → مكونة Button
Card.tsx        → مكونة Card

3. Props واضحة

interface ButtonProps {
  text: string;
  onClick: () => void;
  variant?: "primary" | "secondary";
}

4. تجنب المكونات الكبيرة جداً

إذا كان المكوّن أكبر من 200 سطر → قسّمه.

5. استخدم أسماء وصفية

✅ <UserProfileCard />
❌ <Card1 />

تمارين عملية

تمرين 1: مكوّنة Button

أنشئ مكوّنة Button تقبل text و onClick.

الحل:

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.

الحل:

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.

الحل:

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 اختياري.

الحل:

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.

الحل:

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.

الحل:

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

السبب: لم تستورد المكوّنة.

الحل:

import MyComponent from "./MyComponent";

🔴 المشكلة 2: Type 'X' is not assignable to type 'Y'

السبب: Props بنوع خاطئ.

الحل: تحقق من الـ interface.

🔴 المشكلة 3: المكوّنة لا تظهر

السبب: لم تُرجع JSX.

الحل:

function MyComponent() {
  return <div>محتوى</div>;  // ← يجب أن يكون هناك return
}

🔴 المشكلة 4: key مفقود في القائمة

الحل: أضف key فريد.

جدول مقارنة:

النوعFunctionClass
الصيغةfunction Fn() {}class Fn extends Component
State✅ Hooks⚠️ this.state
الحجم🪶 صغير📦 كبير
الحداثة✅ حديث⚠️ قديم
الاستخدام✅ موصى به❌ تجنبه

قائمة تحقق نهائية

المهمةالحالة
فهم أنواع المكونات⬜
إنشاء مكونات بسيطة⬜
استخدام Props⬜
تمرير Children⬜
تركيب المكونات⬜
بناء تطبيق المدونة⬜
حل التمارين الستة⬜

ماذا بعد هذا المقال؟

الآن بعد أن أتقنت المكونات، أنت جاهز للمقال التالي:

  1. State — إدارة البيانات المتغيرة.
  2. الأحداث — التعامل مع تفاعل المستخدم.
  3. useEffect — التأثيرات الجانبية.

الخلاصة

في هذا المقال، تعلمت:

  • ✅ ما هي المكونات ولماذا نحتاجها.
  • ✅ أنواع المكونات (Function, Class).
  • ✅ Props وكيفية تمريرها.
  • ✅ Children وتركيب المكونات.
  • ✅ أفضل ممارسات تنظيم المكونات.
  • ✅ Props Drilling ومشكلته.
  • ✅ حل 6 تمارين عملية.

تذكر: المكونات هي أساس React. أتقنها جيداً، وستتمكن من بناء أي تطبيق.

هل أتقنت المكونات؟ شاركنا في التعليقات!

📚 مقالات ذات صلة

React

مشروع React متكامل — تطبيق متجر إلكتروني 2026

مشروع عملي شامل لبناء تطبيق متجر إلكتروني بـ React و TypeScript — مع السلة، البحث، التصفية، والحفظ التلقائي

React

Context API في React — إدارة الحالة العامة 2026

دليل عملي مفصل لـ Context API في React — إنشاء Context، Provider، useContext، مع تمارين وحلول

React

React Router — التنقل بين الصفحات في React 2026

دليل عملي مفصل لـ React Router — التنقل، المسارات، الروابط، والمعاملات، مع تمارين وحلول