سه الگوی پر کاربرد در ReactJS

سلام دوستان

در این نوشته اشاره ای می کنم به سه تا الگوی پرکاربرد در ReacJS. به احتمال زیاد این الگوها رو هنگام استفاده از کتابخانه ها و یا در نمونه کدهای مختلف دیدین و تجربه ی استفاده هم داشتید. در اینجا هم میخوام باهم نگاهی به پشت پرده این الگو ها بندازیم و ببینیم چطور پیاده سازی میشن و دقیقا چه مزایایی برای ما دارن.

سه الگوی پرکاربرد در reactjs
سه الگوی پرکاربرد در reactjs

الگوی Function as Child (تابع به عنوان فرزند)

در این الگو در واقع React به ما اجازه میده که یک تابع را به عنوان فرزند به کامپوننت بفرستیم.

? پارانتز باز:

فرزند یا فرزندان داخل یک کامپوننت در اجرای کلاس یا تابع کامپوننت تحت عنوان یک prop به نام children به کامپوننت ارسال میشه.

پارانتز بسته!

الگوی نمونه رو در کد زیر مشاهده میکنید:

https://gist.github.com/behnamazimi/e9534782ef5a805f130c5b52d95d6d17

در کارکرد استاندارد در واقع ما با ارسال تابع فرزند انتظار داریم که اون تابع به عنوان متد رندر کامپوننت عمل کنه. الان باید ببینیم که داخل کامپوننت Calculator چه اتفاقی باید بیفته تا چیزی که انتظار داریم انجام بشه.

https://gist.github.com/behnamazimi/ad79e92751aa422f9df55eb79efd5e04

همونطور که میبینید، کامپوننت MyComponent به عنوان مقدار برگشتی، نتیجه ی اجرای پراپرتی children رو برمیگردونه. یعنی در واقع متدی که به عنوان فرزند بهش پاس دادیم (که چون متد هست پس قابل فراخوانی هم هست) رو اجرا میکنه و نتیجه ی اجرای اون تابع به عنوان مقدار برگشتی MyComponent رندر میشه.

این الگو کاربردهای زیادی داره. مثلا وقتی بخواید روی پراپرتی های یک کامپوننت محاسباتی انجام بدید و یا وقتی بخواید مقادیر async رو کنترل کنید میتونید از این الگو استفاده کنید.

در مثال پایین از این الگو استفاده کردم تا یک کامپوننت کنترل انیمیشن خیلی ساده درست کنم. کامپوننتی به اسم TranslateX که قرار هست المان های زیرش رو به صورت افقی از یک نقطه به نقطه ی دیگه جابجا کنه.

https://gist.github.com/behnamazimi/fe445586b8261b0dd880756d90c5d988
https://codesandbox.io/s/blissful-bell-lm5td

نکته ای که باید بهش توجه کنید اینه که تابعی که به عنوان فرزند به یک کامپوننت پاس میدیم، یک تابع ساده است و نمیتونه نقش یک Functional Component رو برامون بازی کنه. یعنی در واقع react در هر بار رندر کامپوننت به جای اینکه کامپوننت (های) فرزند رو صدا بزنه و رندر کنه، یک تابع معمولی رو دوباره فراخوانی میکنه. در نتیجه در داخل Child Function نمیشه از hook ها و متد های Lifecycle استفاده کرد.


الگوی HOC یعنی Higher-order components

الگویی کاربردی دیگه ای که قراره بررسی کنیم HOC هست. به احتمال زیاد این الگو رو بارها در کدهای react دیدین.

https://gist.github.com/behnamazimi/db6f49f993e6d2d1c41b28d6bf9e97c8https://gist.github.com/behnamazimi/9f8c91e2ab168dea77711961b250fbfb

? پارانتز باز:

در برنامه نویسی یک تعریف داریم به اسم تابع بالا مرتبه و یا higher-order function. برای اینکه بتونیم بگیم یک تابع HO هست یا نه حداقل باید یکی از شرایط زیر در موردش صادق باشه:

  • یک یا چند تابع دیگه رو به عنوان ورودی (argument) بگیره
  • نتیجه ای که برمیگردونه یک تایع باشه

پارانتز بسته!

با استناد به پارانتزی که بالا باز کردم و همینطور با توجه به اینکه میدونیم هر کامپوننت react هم در واقع یک function هست پس دور از انتظار نیست که یک Component داشته باشیم که تابع یا توابعی رو به عنوان پراپرتی بگیره ویا یک تابع رو به عنوان خروجی برگردونه. در react به کامپوننتی که حداقل یکی از ورودی هاش و خروجیش کامپوننت باشه میگیم Higher-order Component.

در یک توضیح کامل تر، HOC کامپوننتی هست که به عنوان یک لایه برای کامپوننت ورودی (کامپوننتی که به عنوان پارامتر به تابع فرستاده میشه) عمل میکنه. یعنی کامپوننت رو میگیره و بعد از انجام یک سری عملیات یک کامپوننت دیگه رو به عنوان خروجی برگشت میده.

https://gist.github.com/behnamazimi/db6f49f993e6d2d1c41b28d6bf9e97c8

زمانی که بخوایم عملیات مشترکی روی کامپوننت ها انجام بدیم اون عملیات رو در قالب یک HOC پیاده سازی میکنیم و در مواقع نیاز HOC رو همراه با کامپوننت هدف صدا میزنیم. مثلا در مثال withSomething من خواستم که پراپرتی something رو به کامپوننت هام اضافه کنم. پس MyComponent رو به تابع withSomething پاس دادم و اون هم بعد از اضافه کردن پراپرتی مورد نظر به کامپوننت من، در خروجی یک کامپوننت جدید برام برگشت داده.

الگوی Sub Components ویا Dot notation components

https://gist.github.com/behnamazimi/5fe5f2d5d8700cb3c644c95edeaecb1a

تا حالا با کامپوننت های آماده ای کار کردید که sub-component هم داشته باشن؟ در واقع اکثر کتابخانه های UI از این ویژگی استفاده میکنند. یعنی یک کامپوننت که چند کامپوننت دیگه رو به عنوان زیرمجموعه اش داره.

میشه گفت رابطه ی این زیر کامپوننت ها با والدشون دقیقا به اندازه یک نقطه است.

? پارانتز باز:

برای درک این الگو نیازه که با مفهوم پراپرتی ها و متدهای static در جاوا اسکریپت آشنا باشید. توضیح این مفهوم در یک پارانتز کوچک جا نمیشه برای همین مطالعه اش به عهده خودتون.

پارانتز بسته!

برای پیاده سازی این الگو روش های مختلفی وجود داره که من در زیر چند موردش رو مثال زدم

https://gist.github.com/behnamazimi/7f5ec9eb31ab71ee1bc59e0cb143462c

معمولا برای دسته بندی کامپوننت ها تحت یک اسم و بالا بردن خوانایی کد و دسترسی سریع به کامپوننت ها از این الگو استفاده میکنیم.

امیدوارم این مطلب براتون مفید واقع بشه. نظراتتون خوشحالم میکنه. :)

در ادامه چند تا از مطالب قبلیم رو هم لینک کردم. باعث افتخاره که بخونید و نظرتون رو بنویسید. سوالی هم بود در خدمتتون هستم.

برای مطالعه نوشته هام منو در توییتر دنبال کنید.