حسان امینی لو
حسان امینی لو
خواندن ۷ دقیقه·۵ سال پیش

۸ نکته برای داشتن کد بهتر در React Native

در طی سال هایی که به صورت حرفه ای مشغول برنامه نویسی هستم تقریبا در هیچ زمانی از نحوه کد زدنم راضی نبودم تا اینکه یک بار گفتم بهتره یه تغییراتی توش بدم و ببینم مشکل کجاست و کجای کارم رو میتونم بهبود بدم.

این ماجرا مربوط به تجربیات من در Refactor کردن بخشی از یکی از محصولات شرکتمون هست که دوست دارم اون تجربیات رو با شما به اشتراک بذارم.

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

خوب ... شروع کنیم!

۱. ساختار پروژه رو به صورت قابلیت-محور(Feature-base) بچینید

راه های مختلفی برای ساختار دادن به پروژه های React وجود داره اما خوشبختانه و یا متاسفانه React و در کل JavaScript برای پروژه شما ، ساختاری رو مشخص نمیکنه و دست شما برای چیدمان فایلها و امکانات سیستم کاملا بازه که البته از یک منظر خوب و از منظر دیگر خیلی هم خوب نیست !

بر مبنای مواردی که در داکیومنت React پیشنهاد شده میتونیم فایلهای پروژه رو به دو صورت تقسیم کنیم :

  • بر اساس نوع فایل
  • بر اساس امکانات (قابلیت های اپلیکیشن)

بر اساس تجربه من که در هر دو مدل کار کردم ، مورد دوم تجربه بهتر و راحت تری بود.

در اینجا مثالی از نحوه ای که من این کار رو انجام دادم می بینید:

عکس ها مفهومی هستند و صرفا برای رسوندن منظور هستند و معنی دیگه ای ندارند
عکس ها مفهومی هستند و صرفا برای رسوندن منظور هستند و معنی دیگه ای ندارند

به نظر که خیلی مرتب و تمیز میاد ! اینطور نیست ؟ پس بهتره با هم یکم موضوع رو عمیق تر بررسی کنیم.

در این مدل فرض کنید یک تیم در حال توسعه یک اپلیکیشن هست و هر کدوم از برنامه نویس ها روی یک Feature کار می کنند ، در این حالت ممکنه تعداد خیلی زیادی فایل ایجاد بشه که شما در طی کارتون بهشون نیازی نداشته باشید و یا حتا براتون دردسر ساز هم بشن ! بعنوان مثال ، یک برنامه نویس مبتدی کد نیمه کاره ای رو Push کرده که در روند توسعه کد شما اخلال بوجود آورده و یا خیلی از موارد پیش بینی نشده دیگه ...(امیدوارم متوجه اصل داستان شده باشید)

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

در این شرایط امکان بوجود اومدن مشکل Require Cycle هم افزایش پیدا میکنه.

و اما برگردیم سر اصل موضوع که همون مدل قابلیت-محور (Feature-Base)بود:

عکس ها مفهومی هستند و صرفا برای رسوندن منظور هستند و معنی دیگه ای ندارند
عکس ها مفهومی هستند و صرفا برای رسوندن منظور هستند و معنی دیگه ای ندارند

طبق این مدل هر کدوم از قابلیت های اپلیکیشن به همراه همه نیازمندی ها و وابستگی هایی که داره داخل یک فولدر Pack میشه، بعنوان مثال برای توسعه صفحه کمپین ها ما فقط با یک فولدر سر و کار داریم، درنتیجه بعد از Scale شدن کار کاملا مشخصه که هر فایل و کامپوننت مربوط به کجاست و مربوط به چه Feature ای هست!

همینطور در مورد تست نوشتن ها که میتونه برای هر Feature داخل فولدر خودش انجام بشه که طبعا با بقیه امکانات سیستم تداخلی نداره و همچنین امکان بوجود اومدن مشکل Require Cycle هم کمتر میشه و میتونیم بخشهای دیگه رو هم راحتتر به اون اضافه کنیم.


۲. همه جا از Functional Component ها استفاده کنید!

ما از Functional component ها استفاده میکنیم چون‌:

  • با کلمه کلیدی this سر و کار نداریم
  • فهمیدنشون راحته
  • تست پذیر تر هستند
  • در مقایسه با Class component ها مقداری سریع تر هستند
  • کوچک هستند

در مورد هر کدوم از موارد بالا میشه یک مقاله مفصل نوشت! اما به طور مختصر میتونیم بگیم معمولا برای رندر کردن اجزای کوچک صفحه نیازی به استفاده از Class component ها نیست و میشه خیلی ساده با یک تابع ساده اون ها رو بوجود آورد. خب چرا که نه؟!

۳. حتما HOC ها رو در نظر بگیرید

در صورتی که یک منطق مشترک یا رفتار مشابه بین چند کامپوننت دارید یا میخواید دیتای خاصی به همه کامپوننت های زیر مجموعه تزریق بشه میتونید از HOC ها استفاده کنید.

مثلا میتونید وضعیت Network رو در یک HOC بررسی کنید و در همه کامپوننت های زیر مجموعه وضعیت اون رو نمایش بدید یا کنترل کنید.

یا اینکه تصور کنید قصد دارید حرکت کاربر بین صفحات اپلیکیشن رو تحت نظر داشته باشید و لاگ اون رو ثبت کنید . طبیعتا باید یک تابع رو بار ها و بار ها در مواقع مختلف صدا بزنید که در این حالت میتونید با استفاده از یک HOC این منطق رو پیاده سازی کنید و اون رو بین همه صفحات دیگه به اشتراک بزارید و همینطور اطلاعات مربوط به اشتراکات این تبلیغات رو بین صفحات پخش کنید. (در واقع شما با اینکار DRY کد میزنید.)


۴. کامپوننت های بزرگ رو تا جاییکه امکان داره به کاپوننت های کوچکتر تقسیم کنید!

هر کامپوننت بزرگ میتونه به کامپوننتهای کوچکتر تقسیم بشه که این موضوع به زیباتر شدن و قابل فهم تر شدن کاپوننتها برای ما کمک زیادی میکنه ، بعنوان مثال به کامپوننت زیر توجه کنید:

که میتونه به کاپوننتهای کوچکتری تقسیم بشه:

و در نهایت در فایل components.js داریم:

خیلی ساده اما بسیار کارامد!

۵. از ESLint استفاده کنید (دستخط خودتون رو داشته باشید!)

لینتر ابزار خیلی خوبیه برای اینکه بتونید کد تمیز تر، کم ایراد تر و به طور کل با کیفیت تری بنویسید.

کدهایی که پتانسیل تبدیل شدن به ارور رو دارند رو بهتون نشون میده، مجبورتون میکنه طبق قواعدی خاص کد بزنید (که این قواعد رو یا از Code style های معروف مثل Airbnb بردارید یا خودتون برای خودتون اون رو بوجود میارید) که این باعث یکدست شدن دست خط شما با اعضای دیگه تیم میشه.

این مثال ساده رو در نظر بگیرید:

قبل از اعمال تغییرات ESLint
قبل از اعمال تغییرات ESLint


بعد از ESLint
بعد از ESLint

میتونید از پلاگین هایی که برای VSCode ساخته شدن هم استفاده کنید که دلیل هر یک از این تغییرات رو هم براتون به شکل یک صفحه documentation نشون میده. فقط کافیه در VSCode داخل تب Extenstions کلمه ESLint رو سرچ کنید و پر دانلود ترین رو انتخاب و نصب کنید.


۶. از امکانات جدید React مثل Hooks بهره بگیرید

به کمک قابلیت جدید React یعنی hook ها! شما امکان داشتن state حتی داخل functional-component ها رو خواهید داشت. قبلا برای نمایش اطلاعات داخل functional-component ها شما میبایست حتما به وسیله  props این کار رو انجام میدادید ولی حالا hook ها این امکان رو به ما میدن که داخل functional-component ها هم state و اطلاعات خاص خودشون رو داشته باشیم.

اما اینجا میخوام در مورد custom hooks صحبت کنم

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

برای دریافت گل ها از hook ها استفاده کردیم. اما خب بهتره که منطق دریافت اطلاعات رو به جای دیگه ای ببریم و اینجا رو خلوت تر کنیم!

برای همین یک custom hook مینویسیم که برای ما اینکارو انجام بده:

مرسوم هست که اول اسم custom hook ها با use شروع بشه
مرسوم هست که اول اسم custom hook ها با use شروع بشه

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

همونطور که میبینید در منطق و کارکرد این کامپوننت تغییری ایجاد نمیشه ولی درنهایت کد بسیار تمیزتر و خوانا تر هست که تست کردن هردوی این توابع بهینه تر و حتی نوشتن تست هم ساده تر میشه.

۷. کامنت ها رو جدی بگیرید

این موضوع دیگه تکراری و کلیشه ای شده که کد شما باید همیشه بصورت self-document باشه به این معنی که با رعایت کردن چند convention برای نام گذاری ویا رعایت بعضی best practice ها و استفاده از ساختار های استاندارد، کاری کنیم تا کسی برای فهمیدن و سر در آوردن کدهای ما خودش رو به زحمت نیندازه و به راحتی براش قابل فهم باشه.

گرچه این مساله کاملا به جا و درسته اما چیزی از ارزشهای والای کامنت گذاری کم نمیکنه.

خلاصه اینکه بهتره سعی کنیم برای قسمت هایی از کد که ممکنه فهمشون مشکل تر از بقیه سیستم باشه کامنت هایی رو قرار بدیم که نحوه کار اون قسمت رو خوب توضیح بده. مثلا این میتونه در مورد توابع ورودی ها و خروجی تابع باشه.

همچنین میتونیم از استاندارد هایی مثل Jsdoc هم استفاده کنیم که این امور رو برای ما ساختار یافته تر انجام بده.

کد با کامنت شکیل تره!
کد با کامنت شکیل تره!

میتونید لیستی از همه نکته ها و مواردی که میتونید توی کامنت ها بنویسید رو توی این لینک ببینید.


۸. کاستوم پکیج های NPM (اسم من دراوردی)

همه مون این مورد رو دیدیم:

گم شدن توی چنین وضعیتی چقدر راحته
گم شدن توی چنین وضعیتی چقدر راحته

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

میتونیم خیلی ساده هر کدوم از این اجزا رو به یک ماژول npm تبدیل کنیم و هرجایی که نیاز داشتیم شکل یک پکیج third-party اونها رو import کنیم.

مرتب و تمیز
مرتب و تمیز

همینطور که میبینیم کار رو برای ما ساده تر میکنن.

داخل هر فولدری که خواستید این پکیج ها رو قرار بدید و توی اون فولدر یک فایل package.json ایجاد کنید با این محتوا:

حتما داخل مقدار version از semver باید استفاده کنید
حتما داخل مقدار version از semver باید استفاده کنید

بعد از project root دستور npm install PACKAGE_ADDRESS (به جای PACKAGE_NAME آدرس اون فولدر کاستوم پکیج رو وارد کنید) اجرا کنید تا اضافه بشه.



امیدوارم این نکات براتون مفید بوده باشه. خوشحال میشم نظرات تون رو برام بنویسید.


موفق باشید ?

reactreact nativeبرنامه نویسیrefactoringfront end
برنامه نویس از جلو
شاید از این پست‌ها خوشتان بیاید