اگر از React استفاده کرده باشید، احتمالا اسمی از Higher-order component ها یا HOC شنیده اید. در این مقاله قصد نداریم مفهوم HOC را توضیح دهیم، بنابراین اگر نمی دانید HOC چیست بهتر است سری به مقاله های زیر بزنید.
داکیومنت React و یا ترجمه فارسی آن
همانطور که از عنوان مقاله پیداست می خواهیم پیاده سازی کوچکی از HOC داشته باشیم. رایج ترین مثال از HOC تابع connect در react-redux است. اما بیایید به سراغ اولین مثال استفاده از HOC برویم.
این مفهوم را با حالت های متفاوتی می توان پیاده سازی کرد: نمایش دادن یا پنهان کردن یک المنت، پیاده سازی آکاردئون و ...
نمونه پیاده سازی شده زیر برای نمایش دادن و پنهان کردن المان ها است. فرض کنید کامپوننتی داریم که لیست تسک های کاربر را نشان می دهد. اگر کاربر روی دکمه + کلیک کرد، باید فرم افزودن تسک جدید به کاربر نمایش داده شود و با کلیک مجدد روی دکمه، فرم پنهان شود.
اول بدون استفاده از HOC کامپوننت فرم را پیاده سازی می کنیم.
در این حالت ما یک state برای نگهداری وضعیت نمایش فرم به نام formIsShown در نظر می گیریم، که در رویداد کلیک دکمه + آن را تغییر می دهیم. برای رندر شدن یا نشدن فرم نیز از همین مشخصه و Conditional rendering استفاده می کنیم.
بعد از پیاده سازی، با توجه به این نکته که عمکرد نمایش دادن و پنهان کردن یک المان ممکن است در بخش های مختلفی از پروژه استفاده شود، آن را به یک HOC تبدیل می کنیم تا بتوانیم در سایر کامپوننت ها نیز از این منطق پیاده سازی شده استفاده کنیم.
ابتدا یک Higher-order component برای پیاده سازی منطق Toggling می سازیم.
تابع HOC تعریف شده یک کامپوننت را به عنوان ورودی دریافت می کند، اما کامپوننتی که بر می گرداند شامل دو prop جدید با نام های isShown و toggleIsShownHandler می باشد.
نکته مهم: حتما props کامپوننت دریافتی را در کامپوننت خروجی ارسال کنید، تا مطمئن شویم که HOC فراخوانی شده روی کامپوننت، باعث تغییر عملکرد و ظاهر آن نشده است.
در نهایت برای استفاده از این منطق در هر کامپوننتی کافی است آن را روی کامپوننت موردنظر فراخوانی کنید.
export default withToggle(TaskForm);
در این حالت در کامپوننت TaskForm شما علاوه بر Property های خود کامپوننت، دو مشخصه جدید با نام های isShown و toggleIsShownHandler دارید.
سورس نمونه نوشته شده را می توانید در لینک زیر پیدا کنید:
https://codesandbox.io/s/toggleshow-9eir5?fontsize=14
در تمامی پروژه ها زمانی که می خواهیم داده ای را از یک Api بارگذاری کنیم و در صفحه نمایش دهیم، برای مدت زمان کوتاهی صفحه خالی است، چرا که داده موردنظر هنوز کامل لود نشده است. در این حالت بهتر است به جای صفحه خالی، پیغام "در حال بارگذاری" یا انیمشنی به کاربر نشان دهیم.
در حالت عادی پیاده سازی کامپوننت به صورت زیر خواهد بود.
در کامپوننت App دو state تعریف می کنیم.
این دو مشخصه را به کامپوننت Users می فرستیم. پیاده سازی کامپوننت User به شکل زیر خواهد بود.
در کامپوننت Users با توجه به اینکه پراپرتی isLoading چه مقداری دارد، یکی از کامپوننت های Loading یا لیست کاربران نمایش داده می شود.
با توجه به اینکه منطق نمایش دادن Loading در بخش های زیادی از پروژه استفاده می شود، می توان آن را با HOC پیاده سازی و بر کامپوننت های مختلفی اعمال کرد.
در مرحله اول تابع withLoading را پیاده سازی می کنیم، این تابع همان HOC است.
تابع withLoader دو پارامتر دارد، پارامتر اول WrappedComponent است، همان کامپوننتی که قرار است با تغییراتی به خروجی فرستاده شود. پارامتر دوم تعیین کننده نام پراپرتی isLoading است. با استفاده از isLoadingProp و Props کامپوننت Wrapped شده می توان به مقدار isLoading دسترسی داشت.
در مرحله بعد کامپوننت Users را به صورت زیر تغییر می دهیم.
با فراخوانی تابع withLoading روی کامپوننت Users تمامی منطق نوشته شده در تابع روی کامپوننت کاربران اعمال می شود.
خلاصه کاری که Higher-order Component انجام می دهد:
به یاد داشتن این نکته از داکیومنت ری اکت می تواند به درک اینکه کجا باید از HOC استفاده کنیم، کمک کند.
We want an abstraction that allows us to define this logic in a single place and share it across many components. This is where higher-order components excel.
https://medium.com/@soorajchandran/introduction-to-higher-order-components-hoc-in-react-383c9343a3aa