قبل از شروع مقاله بهتره سه نکته رو بیان کنم:
اگر از UI Liberyهایی نظر MUI، React Bootstrap، Mantine و ... استفاده کرده باشید، حتما با این نوع کامپوننتها مواجه شدهاید و حتی ممکنه در پروژههاتون ازش استفاده کرده باشید، هرچند ممکنه از نظر مفهومی با اصلاح آن آشنا نباشید.
در این بخش می خواییم در این مورد صحبت کنیم که:
قبل از پاسخ به سوال اول بهتره این رو توضیح بدیم که Polymorphism چی هست. برای پاسخ به این سوال من از مقالهای که در بلاگ فرادرس در این مورد منتشر شده کمک میگیرم:
باید گفت که پلی مورفیسم (Polymorphism | چندریختی) واژهای یونانی به حساب میآید، در لغت به معنی «داشتن چندین شکل و فُرم مختلف» است. در کل اصطلاح Polymorphism یعنی:
شرایط رخ دادن و به وقوع پیوستن در فُرمهای مختلف
در علوم کامپیوتر و برنامه نویسی شی گرا ، شی دارای چند ریختی به شیئی گفته میشود که میتواند چندین فُرم و شکل را به خود بگیرد.
برای اینکه بتوان مشخص کرد که آیا یک شی دارای حالت چندریختی یا به اصطلاح «پلی مورفیک» (Polymorphic) هست یا خیر، میتوان یک آزمایش ساده انجام داد. در صورتی که آزمونهای «is-a» (آیا هست؟) یا «instanceof» (نمونهای از) برای آن شی موفقیتآمیز باشند، آن شی چندریختی دارد و به اصطلاح «پلی مورفیک» است.
به بیان ساده، چندریختی یا پلی مورفیسم (Polymorphism) در برنامه نویسی، استفاده از یک بلوک کد و تغییر «نسخه» آن بلوک کد، بر اساس نوع ورودیها است. اصطلاح پلی مورفیسم یا چندریختی در برنامه نویسی و علوم کامپیوتر به این معنا است که میتوان به اشیایی با انواع مختلف از طریق رابط و واسطی یکسان دسترسی داشت.
حالا با دونستن معنی Polymorphism میتونیم حدس بزنیم در لایبری ریاکت به چه کامپوننتهایی Polymorphic Component میگن. در واقع Polymorphic Component به کامپوننتهایی گفته میشوند که از طریق یک پراپس/ورودی (معمولا به نام "as" یا "component") میتوان تعیین کرد که در زمان رندرِ کامپوننت، چه المنتی از المنتهای HTML در DOM رندر شود.
یعنی به جای اینکه از چندین کامپوننت جداگانه برای نمایش المنتهای مختلف استفاده کنیم، یک کامپوننت را با استفاده از پارامترهای متفاوت ورودی، سفارشیسازی کنیم. مثلاً فرض کنید یک کامپوننت با نام "Button.tsx" داریم که برای نمایش دکمهها استفاده میشود. با استفاده از Polymorphic Component میتوانیم این کامپوننت را به گونهای پیادهسازی کنیم که نوع المنت دکمه به عنوان ورودی قابل تنظیم باشد. (مثلا تگ "a" باشد یا تگ "button" و ...)
برای اینکه بتونیم بگیم یک کامپوننت، Polymorphic یا چندریختی/چندشکلی هست، حداقل باید دارای چهار ویژگی/ملزومات زیر باشد: (پیشنهاد میکنم که این ویژگیها رو حتما بهخاطر بسپارید یا در جایی یادداشت کنید، چون در بخشهای بعدی هر کدوم از این موارد رو باید پیادهسازی کنیم)
1. کامپوننتمان باید یک پراپس به عنوان ورودی جهت تعیین نوع المنت قبول کند. (در این مقاله ما از نام "as" استفاده می کنیم)
2. مقداری که به پراپس "as" پاس میدهیم باید در DOM رندر شود. (مثلا تگ span)
3. کامپوننت باید موارد زیر نیز پشتیبانی کند:
- اتریبیوتهای سراسری/گلوبال مانند id یا class و ...
- از اتریبیوتهای مختص با المنت تعیین شده، مانند src در تگ img یا href در تگ a و ...
- پراپسهای کاستوم/سفارشی در کامپوننتهای دیگر یا Third Party مثلا کامپوننت Link در فریمورک NextJs پراپسهایی مانند replace یا prefetch و ... را دارد.
4. در هنگام توسعه به صورت Type Safety پیادهسازی شده باشد، در نتیجه؛ تایپاسکریپت در موراد زیر باید خطا نمایش دهد:
- اگر مقدار پاس داده شده به پراپرتی as از نوع المنتهای معتبر در HTML نباشد. (مثلا المنت test در HTML معتبر نیست و در نتیجه نمیتوان از آن استفاده کرد)
- اگر از اتریبیوتِ اشتباهی که مختص به آن المنت نیست، استفاده شود. مثلا تگ img اتریبیوت href را ندارد.
- اگر مقدار ref اشتباهی به کامپوننت پاس داده شود. (در مورد کامپوننتهایی که قابلیت forwardRef را دارند.) مثلا کامپوننت ما یک button است ولی مقدار ref به یک المنتی غیر از button اشاره میکند.
بنظرم برای بخش اول تا همینجا کافی هست. مابقی موارد رو در بخشهای دیگه سعی میکنم توضیح بدم.
اگر مورد خاصی برای بخش اول بهتر هست گفته بشه که از قلم افتاده یا اشتباهی در نگارش وجود داره ممنون میشم از طریق نظرات بهم اطلاع بدید تا ویرایش لازم رو انجام بدم.
ضمنا منابعی که من برای نوشتن این مجموعه مقالات استفاده کردم فعلا موارد زیر هست: