المكونات الوظيفية في React — معيار التطوير الحديث

المؤلف: IT Sectr نُشر: 2026-07-04 وقت القراءة: 9 دق

Functional Component — هي طريقة لإنشاء مكونات React باستخدام دوال JavaScript العادية، والتي أصبحت المعيار بعد إصدار React 16.8 وظهور الهوكس. تقبل المكونات الوظيفية props وتعيد عناصر React دون الحاجة إلى وراثة React.Component. وفقاً لـ React، 2024، 97% من المكونات الجديدة في نظام React البيئي تُكتب كدوال.

النقاط الرئيسية

  • Functional Component — دالة JavaScript عادية تقبل props وتعيد JSX، بدون extends Component.
  • الهوكس (useState, useEffect, useContext) تمنح المكونات الوظيفية وصولاً كاملاً للحالة ودورة الحياة.
  • قابلية القراءة — المكونات الوظيفية أقصر من المكونات الصفية، بدون constructor أو bind أو طرق دورة حياة إضافية.
  • الأداء — React تحسن المكونات الوظيفية من خلال التخزين المؤقت (memoization) والتهيئة البطيئة.
  • توصية React — يجب أن تستخدم جميع المشاريع الجديدة المكونات الوظيفية مع الهوكس فقط.

ما هو Functional Component؟

Functional Component هو مكون React يُعرف كدالة تقبل كائن props وتعيد عنصر React. قبل React 16.8، كانت هذه المكونات تسمى عديمة الحالة (stateless) لأنها لم تكن تستطيع إدارة الحالة الداخلية.

مع ظهور الهوكس في React 16.8 (فبراير 2019)، حصلت المكونات الوظيفية على إمكانية الوصول إلى الحالة (useState)، التأثيرات الجانبية (useEffect)، السياق (useContext) والمراجع (useRef). مصطلح ‘عديمة الحالة’ أصبح قديماً — المكونات الوظيفية الحديثة تدير الحالة بشكل كامل.

توصي React رسمياً بالمكونات الوظيفية كـ طريقة رئيسية لإنشاء المكونات. جميع الوثائق على react.dev، الأمثلة، الدروس التعليمية وواجهات API الجديدة (Server Components, Actions) مبنية على النهج الوظيفي. لم تتم إزالة المكونات الصفية، لكن الميزات الجديدة لـ React متاحة فقط من خلال الهوكس.

إنشاء مكون وظيفي

أبسط مكون وظيفي هو دالة تعيد JSX. يقبل props كوسيط، لا يتطلب constructor أو استدعاء super أو ربط this. الـ props متاحة مباشرة من خلال وسيط الدالة — لا حاجة لـ this.props.

js
// Functional component without state
function Greeting({ name }) {
  return <h1>Hello, {name}!</h1>;
}

// Arrow function (common variant)
const Greeting = ({ name }) => (
  <h1>Hello, {name}!</h1>
);

مكون مع حالة

لإضافة حالة، استخدم useState. يعيد الهوكس مجموعة من قيمتين: الحالة الحالية ودالة التحديث. على عكس this.setState في الصفوف، يستبدل useState القيمة بالكامل بدلاً من دمجها مع السابقة.

js
import React, { useState } from 'react';

function Counter() {
  const [count, setCount] = useState(0);

  return (
    <div>
      <p>You clicked {count} times</p>
      <button onClick={() => setCount(count + 1)}>
        Increment
      </button>
    </div>
  );
}

الهوكس في المكونات الوظيفية

الهوكس هي أساس React الحديث. كل هوكس يحل مهمة محددة: useState — الحالة، useEffect — التأثيرات الجانبية، useContext — الوصول إلى السياق، useRef — مراجع عناصر DOM، useCallback و useMemo — التخزين المؤقت.

useEffect للتأثيرات الجانبية

يستبدل useEffect كلاً من componentDidMount و componentDidUpdate و componentWillUnmount معاً. الوسيط الأول هو دالة الاستدعاء مع التأثير، والثاني هو مصفوفة التبعيات. إذا كانت المصفوفة فارغة، يتم تنفيذ التأثير مرة واحدة بعد التثبيت. إذا تم تحديد تبعيات، يتم التنفيذ عندما تتغير أي منها.

js
import React, { useState, useEffect } from 'react';

function UserData({ userId }) {
  const [user, setUser] = useState(null);

  useEffect(() => {
    let cancelled = false;

    fetch(`/api/users/${userId}`)
      .then(res => res.json())
      .then(data => {
        if (!cancelled) setUser(data);
      });

    // Cleanup - analog of componentWillUnmount
    return () => { cancelled = true; };
  }, [userId]); // Dependency

  return <div>{user?.name}</div>;
}

الهوكس المخصصة

الميزة الرئيسية للمكونات الوظيفية هي إعادة استخدام المنطق من خلال الهوكس المخصصة. بينما في المكون الصفي كان المنطق يتكرر بين componentDidMount و componentDidUpdate، في المكون الوظيفي يتم استخراجه في دالة منفصلة ببادئة use. الهوكس المخصصة هي البديل الرئيسي لـ HOC و render props.

التركيب بدلاً من الوراثة

توصي React بـ التركيب بدلاً من الوراثة لإعادة استخدام الكود بين المكونات. المكونات الوظيفية مثالية للتركيب: يمكن لمكون واحد أن يحتوي على عدة مكونات أخرى، ويمرر لها props و children.

نمط children — عندما يستقبل المكون عناصر فرعية من خلال prop children — يتم تنفيذه بشكل طبيعي: function Layout({ children }). يتم تنفيذ ما يعادل slots في Vue من خلال props مكونات مسماة: function Page({ header, sidebar, content }).

الوراثة نادراً ما تستخدم في React. حتى المكونات الصفية، التي تدعم extends تقنياً، نادراً ما تشكل تسلسلات هرمية أعمق من مستوى واحد. المكونات الوظيفية مع التركيب تغطي تماماً احتياجات إعادة استخدام الكود دون وراثة.

تحسين الأداء

تأتي المكونات الوظيفية مع آليات تحسين مدمجة. React.memo — ما يعادل PureComponent للدوال: يمنع إعادة التصيير إذا لم تتغير props (مقارنة سطحية). useMemo يخزن نتائج الحسابات بين عمليات التصيير.

js
import React, { useMemo } from 'react';

// React.memo - memoize component
const ExpensiveList = React.memo(({ items }) => {
  return <ul>
    {items.map(item =>
      <li key={item.id}>{item.name}</li>
    )}
  </ul>;
});

// useMemo - caching result
function Dashboard({ transactions }) {
  const summary = useMemo(() => {
    return transactions.reduce((acc, t) => acc + t.amount, 0);
  }, [transactions]);

  return <p>Total: {summary}</p>;
}

useCallback يخزن دوال الاستدعاء مؤقتاً حتى لا يتم إعادة إنشائها في كل تصيير. هذا أمر حاسم عند تمرير دوال إلى مكونات فرعية مغلفة بـ React.memo: بدون useCallback، سيتم إعادة تصيير المكون الفرعي في كل مرة لأن مرجع الدالة يتغير.

المكونات الوظيفية مقابل الصفية

الفرق بين النهجين يتجاوز بناء الجملة. المكونات الوظيفية هي closures: الحالة والتأثيرات مرتبطة بتصيير محدد. المكونات الصفية تستخدم this: الحالة تؤخذ دائماً من this.state، والتي قد تكون قديمة وقت تنفيذ دالة استدعاء غير متزامنة.

الجانبوظيفيصفي
الحالةuseState (معزولة)this.state + this.setState
التأثيراتuseEffect مع تبعياتcomponentDidMount + componentDidUpdate
السياقuseContextContext.Consumer أو static contextType
التحسينReact.memo + useMemoPureComponent + shouldComponentUpdate
إعادة الاستخدامهوكس مخصصةHOC / Render props
thisلا يوجدbind في constructor

توفر المكونات الوظيفية تدفق تنفيذ خطي. في المكون الصفي، غالباً ما يكون المنطق المرتبط مبعثراً عبر طرق دورة حياة متعددة. على سبيل المثال، يتم إعداد اشتراك WebSocket في componentDidMount وإزالته في componentWillUnmount. في المكون الوظيفي، كلتا العمليتين في useEffect واحد مع دالة تنظيف للإرجاع.

TypeScript والمكونات الوظيفية

يعمل TypeScript بشكل أكثر طبيعية مع المكونات الوظيفية مقارنة بالصفوف. كتابة props — واجهة لوسيط الدالة. نوع الإرجاع هو JSX.Element أو ReactNode. يستنتج useState النوع تلقائياً من القيمة الأولية.

ts
import React, { useState } from 'react';

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

const Button: React.FC<ButtonProps> =
  ({ label, variant = 'primary', onClick }) => (
    <button
      className={`btn btn-${variant}`}
      onClick={onClick}
    >
      {label}
    </button>
  );

يسمح TypeScript الحديث بكتابة useReducer بأنواع union متمايزة، والعوامل العامة (Generics) في الهوكس المخصصة، والتحقق الصارم من children من خلال React.PropsWithChildren. توفر المكونات الوظيفية مع TypeScript أماناً كاملاً للأنواع دون تجريدات إضافية.

الأسئلة المتكررة

لماذا توصي React بالمكونات الوظيفية؟

المكونات الوظيفية أبسط: لا يوجد constructor أو bind أو this أو طرق دورة حياة مبعثرة. تسمح الهوكس بتجميع المنطق المرتبط. تستثمر React مواردها في تطوير الهوكس، وليس الصفوف. Server Components والميزات الجديدة متاحة فقط في الدوال.

هل يمكنني استخدام setInterval في مكون وظيفي؟

نعم، من خلال useEffect مع مؤقت داخلي ودالة تنظيف لـ clearInterval. انتبه إلى closure: إذا كنت تزيد عداداً، استخدم الصيغة الوظيفية لـ setState: setCount(c => c + 1) لتجنب الاعتماد على القيمة القديمة في closure.

كيف أحصل على props السابقة في مكون وظيفي؟

استخدم useRef لتخزين القيمة السابقة. قم بتحديث المرجع في useEffect بعد كل تصيير. يساعد هوكس مخصص usePrevious في المقارنة النظيفة: const prev = usePrevious(value);

ما الفرق بين React.memo و useMemo؟

React.memo هو HOC لتخزين مكون كامل مؤقتاً: يمنع إعادة التصيير إذا لم تتغير props. useMemo هو هوكس لتخزين قيمة محددة مؤقتاً داخل المكون: يخزن نتيجة دالة بين التصييرات حسب مصفوفة التبعيات.

كيف أحاكي getDerivedStateFromProps في مكون وظيفي؟

الطريقة الأبسط هي useState مع تهيئة من props + useEffect مع تبعية على props للمزامنة. للحالات النادرة، توصي React باستخدام key لإجبار إعادة إنشاء المكون عندما تتغير بيانات الإدخال.

الخلاصة

  • Functional Component — معيار React الحديث: دالة تقبل props وتعيد JSX.
  • الهوكس (useState, useEffect) تمنح المكونات الوظيفية حالة وتأثيرات وسياقاً دون صفوف.
  • التركيب من خلال children والهوكس المخصصة يحل محل الوراثة وأنماط HOC.
  • React.memo و useMemo يوفران تحسين أداء للمكونات الوظيفية.
  • TypeScript مع المكونات الوظيفية يوفر كتابة صارمة للـ props واستدلالاً تلقائياً للأنواع.
  • useEffect يحل محل جميع طرق دورة حياة المكونات الصفية في مكان واحد.
  • الهوكس المخصصة تسمح باستخراج وإعادة استخدام المنطق بين المكونات دون HOC.

سنقوم بتطوير تطبيق جوال جاهز

تقدم IT Sectr تطبيقات iOS وAndroid للشركات الناشئة والشركات منذ عام 2017. سوف نقدم لك النصح ونقترح أفضل حل.

مناقشة المشروع

اقرأ أيضًا