مكونات الدالة مقابل React.FC
في تايب سكريبت: نقاش حضاري
يدخل React و TypeScript مشروعاً معاً. يقول TypeScript: "سأتولى إدارة الأنواع." ويقول React: "سأتولى عملية العرض." وأثناء هذا الطريق، يسأل أحدهم:
هل يجب أن نستخدم
React.FC
، أم فقط نكتب النوع للدالة مباشرة؟
إنه سؤال منطقي. من النظرة الأولى، يبدو React.FC
مصقولاً ورسمياً — بل شديد الأناقة. كأنه سيقدم لك كأساً من النبيذ ويقول "دعنا نجعل هذا المكون أنيقاً." لكن تحت السطح، يحمل بعض العبء الذي تجاوزته معظم إصدارات تايب سكريبت الحديثة.
دعونا نلقي نظرة أقرب.
الأسلوبان
مكون الدالة العادي
type Props = { title: string };
function MyComponent({ title }: Props) {
return <h1>{title}</h1>;
}
نظيف، واضح، وسهل الفهم. مثل القهوة السوداء: بدون إضافات، فقط يقوم بالمهمة.
أو، إذا كنت تفضل الدوال السهمية:
const MyComponent = ({ title }: Props) => {
return <h1>{title}</h1>;
};
كلاهما صالح، قابل للقراءة، ومتوافق جيداً مع الممارسات الحالية.
نسخة React.FC
import { FC } from 'react';
type Props = { title: string };
const MyComponent: FC<Props> = ({ title }) => {
return <h1>{title}</h1>;
};
هذا النسق يغلف المكون بنوع عام (Generic Type). يبدو أكثر "رسمية"، وإذا كنت قد اكتشفت مؤخراً أنواع الأدوات في تايب سكريبت، قد تشعر بأنه ملائم بطبيعة الحال — كأنك فتحت باب نادٍ سري. لكن أحياناً، الأندية السرية تأتي مع شروط دقيقة.
ما الذي يفعله React.FC فعلياً
React.FC (اختصار لـ React.FunctionComponent) هو نوع مساعد يصف مكون دالة. يقدم بعض السلوكيات الافتراضية:
- يضيف خاصية children بشكل افتراضي، سواء أردت ذلك أو لا.
- قد يعزز الإكمال التلقائي في بعض المحررات أحياناً.
- قد يجعل نوع الإرجاع للدالة أكثر وضوحاً، رغم أن ذلك نادراً ما يكون مهماً في الممارسة.
هذه تسهيلات متواضعة، وكانت أكثر فائدة في أيام React + TypeScript الأولى. لكن الزمن تغير، والآن غالباً ما تعيق هذه "الميزات" أكثر مما تساعد.
لماذا بدأ يفقد شعبيته
يمكن القول إن React.FC يشبه بنطال الحمل بتصميمه العملي في تايب سكريبت — العديد من الجيوب، ومعظمها غير مستخدم.
- الخاصية children الضمنية
كل مكون يحصل على خاصية children سواء احتاجها أم لا. وهذا قد يؤدي إلى أخطاء مربكة عندما يفترض المطورون أن خاصية children متاحة فقط لأن النوع يقول ذلك. (مفاجأة: قد لا تكون كذلك.)
- تعقيد مع الأنواع العامة
عندما يحتاج مكونك لاستخدام الأنواع العامة، يجعل React.FC الأمور أكثر تعقيداً بدلاً من تبسيطها. يصبح بناء الجملة غير سلس، ويصبح تايب سكريبت أقل فائدة.
- طول الكتابة دون وضوح إضافي
كتابة const MyComponent: FC<Props>
أطول، وربما أكثر غموضاً، من كتابة النوع للمُدخلات مباشرة.
- لم يعد ضرورياً
الأسباب الأصلية لاستخدام React.FC — دعم المحررات، استنتاج JSX — تم حلها بشكل كبير بتحسينات تايب سكريبت الحديثة. ما كان في السابق حل عملي أصبح اليوم مجرد أسلوب قديم.
مقارنة جنباً إلى جنب
الخاصية | function Component() | const Component: FC |
---|---|---|
هل يشمل children؟ | فقط إذا تم الإعلان عنها | دائماً مشمول |
دعم الأنواع العامة؟ | بشكل سلس | ليس بدون جهد |
الطول عند الكتابة؟ | قليل | أكثر وضوحاً بشكل ملحوظ |
دعم المحرر؟ | كافٍ | أفضل قليلاً في حالات معينة |
هل يُنصح باستخدامه؟ | نعم | لا بعد الآن |
النهج الموصى به
الإجماع في المجتمع بسيط: اكتب أنواع المُدخلات مباشرة. إذا أردت أن يقبل المكون خاصية children، فقل ذلك صراحةً. وإذا لم ترغب، فلن يكون كذلك. هذه صدقّت المستقبل الذي ستشكرك عليه.
type Props = {
title: string;
children?: React.ReactNode;
};
const MyComponent = ({ title, children }: Props) => (
<div>
<h1>{title}</h1>
{children}
</div>
);
إنه صريح. قابل للصيانة. ولا يتظاهر بأن مكونك يتعامل مع children إذا لم يكن كذلك.
هل هناك مواقف لا يزال React.FC فيها منطقياً؟
أحياناً. إذا كنت تعمل في قاعدة أكواد قديمة تعتمد بشكل كبير على React.FC، قد يكون الحفاظ على الاتساق أكثر أهمية من إعادة كتابة كل شيء. إذا كنت تقوم بسرعة بإنشاء مكونات ولا تريد القلق بشأن كتابة نوع children، قد يبقى React.FC اختصاراً مفيداً.
لكن بشكل عام، هذه هي الاستثناءات التي تؤكد القاعدة.
في الختام
React.FC ليس خطأ. إنه فقط لم يعد ضرورياً. لقد جعل تايب سكريبت الحديث كتابة أنواع مكونات React أبسط وأكثر توقعاً بدونه.
لذا في المرة القادمة التي تفكر فيها في استخدام FC، توقف وتمعّن فيما إذا كنت تضيف قيمة — أو فقط طبقات إضافية. في معظم الأحيان، ستخدمك الدالة المعنونة مباشرة أفضل.
في البرمجة — كما في الحياة — الوضوح أفضل من الذكاء. والمفاجآت الأقل عادة ما تعني ندم أقل.