برنامه نویسی 405 بازدید

React تغییرات بسیاری را شاهد بوده است و هر بار کاربرانش را شگفت‌زده کرده است. ابتدا mixin-ها برای ایجاد و مدیریت اینترفیس معرفی شدند، سپس مفهوم کامپوننت کلاس معرفی شد و اینک قلاب‌های ری‌اکت روش ساخت اپلیکیشن‌ها را متحول ساخته‌اند. در این مقاله در مورد هشت ترفند مفید برای توسعه اپلیکیشن‌های React با شما صحبت خواهیم کرد.

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

1. ایجاد عناصر React با رشته‌ها

نخستین مورد در فهرست ترفندهای ری‌اکت به ایجاد یک عنصر معمولی DOM در ری‌اکت با استفاده از رشته‌های ساده مربوط می‌شود. این رشته‌ها یک تگ عنصر HTML DOM را نمایش می‌دهند که به بیان دقیق‌تر رشته‌ای است که یک عنصر DOM را بازنمایی می‌کند.

برای نمونه می‌توانید کامپوننت‌های ری‌اکت را با انتساب رشته ‘div’ به یک متغیر به صورت زیر ایجاد کنید:

ری‌اکت صرفاً React.createElement را فراخوانی می‌کند و از آن رشته برای ایجاد عنصر به صورت داخلی استفاده می‌کند.

این امکان به طور معمول در کتابخانه‌های کامپوننت مانند Material UI استفاده می‌شود که می‌توانید یک prop به نام component اعلان کنید و فراخوانی کننده در مورد این که کدام گره ریشه کامپوننت می‌تواند به مقدار props.component تعیین شود، تصمیم‌گیری کند:

شیوه استفاده از آن به صورت زیر است:

همچنین می‌توانید کامپوننت سفارشی خود را در جایی که در گره ریشه استفاده خواهد شد ارسال کنید:

2. استفاده از کران‌های خطا

ما در جاوا اسکریپت به طور معمول اغلب خطاها را در بخش اجرای کد با try/catch مدیریت می‌کنیم. در این بلوک کد می‌توانیم خطاهایی را که رخ می‌دهند catch کنیم. هنگامی که این خطاها در بلوک catch گیر می‌افتند، می‌توانیم جلوی از کار افتادن اپلیکیشن را درون کران‌های کد بگیریم. نمونه‌ای از این حالت را در ادامه می‌بینید:

ری‌اکت در نهایت چیزی به جز جاوا اسکریپت نیست و از این رو بسیاری بر این باورند که می‌توانیم خطاها را با استفاده از همین راهبرد گیر انداخته و مدیریت کنیم. با این حال به دلیل ماهیت ری‌اکت، خطاهای جاوا اسکریپت درون کامپوننت‌ها حالت درونی ری‌اکت را از بین می‌برند و موجب بروز خطاهای emit cryptic در رندرهای آتی می‌شوند.

به همین جهت تیم ری‌اکت مفهوم «کران‌های خطا» (error boundaries) را معرفی کرده است که هر توسعه‌دهنده ری‌اکت باید با آن‌ها آشنا باشد و از آن‌ها در اپلیکیشن‌های ری‌اکت خود استفاده کند. مشکل در مورد خطاهایی که پیش از معرفی مفهوم «کران‌های خطا» رخ می‌داد، این بود که وقتی خطاهای cryptic در رندرهای آتی و پس از رخ دادن در رندهای پیشین صادر می‌شدند، ری‌اکت روشی برای مدیریت و بازیابی از این وضعت در کامپوننت‌ها ارائه نمی‌کرد. این همان جایی بود که به مفهوم کران‌های خطا نیاز داشتیم.

کران‌های خطا کامپوننت‌های ری‌اکت هستند که خطاها را هر جایی در درخت کامپوننت به دام می‌اندازند، آن‌ها را لاگ می‌کنند و می‌توانند به جای درخت کامپوننت که از کار افتاده است، UI پشتیبان (fallback) را نمایش دهند.

کران‌های خطا، اقدام به یافتن خطاها در زمان رندر کردن، درون متدهای چرخه عمری و درون سازنده‌های کل درخت زیر خودشان می‌کنند. به همین دلیل است که آن‌ها را در ابتدای اپلیکیشن اعلان و رندر می‌کنیم. در ادامه مثالی از مستندات ری‌اکت را مشاهده می‌کنید:

می‌توانید از آن به عنوان یک کامپوننت معمولی استفاده کنید:

3. حفظ مقادیر پیشین

در زمان به‌روزرسانی props یا حالت می‌توان مقادیر پیشین را صرفاً با استفاده از React.useRef حفظ کرد. برای نمونه برای ردگیری تغییرات کنونی و قبلی آیتم‌های یک ارائه می‌توان یک React.useRef ایجاد کرد که به مقدار قبلی را انتساب یابد و یک React.useRef نیز برای مقدار کنونی تعریف کنیم:

این کد به این دلیل کار می‌کند که React.useEffect پس از پایان یافتن رندرینگ کامپوننت‌ها اجرا می‌شود. هنگامی که setNames فراخوانی می‌شود، کامپوننت مجدداً رندر می‌شود و prefNamesRef نام‌های پیشین را نگهداری می‌کند، زیرا React.useEffect آخرین کدی است که از رندر قبلی اجرا شده است. و از آنجا که prevNamesRef.current را در useEffect مجدداً انتساب دادیم، به نام‌های پیشین در مرحله بعدی رندر تبدیل می‌شود، زیرا نام‌های برجای‌مانده از مرحله قبلی رندر را انتساب می‌دهد.

4. استفاده از React.useRef برای بررسی‌های غیر انعطاف‌پذیر

تا پیش از معرفی قلاب‌های ری‌اکت یک متد استاتیک به نام componentDidMount در کامپوننت‌های کلاس وجود داشت که می‌توانستیم از این که عملیاتی مانند واکشی داده‌ها پس از نصب شدن کامپوننت روی DOM اجرا می‌شوند، مطمئن باشیم.

اما پس از معرفی، قلاب‌های ری‌اکت به سرعت به روشی محبوب برای نوشتن کامپوننت‌ها به جای کامپوننت‌های کلاسی تبدیل شدند. هنگامی که می‌خواهیم بررسی کنیم آیا یک کامپوننت Mount شده یا نه و از تغییر حالت پس از Unmount شدن کامپوننت جلوگیری کنیم، می‌توانیم به صورت زیر عمل کنیم:

قلاب‌ها پس از مهاجرت به React Hooks دیگر componentDidMount ندارند و مفهوم نشت حافظه از به‌روزرسانی حالت پس از unmount شدن کامپوننت همچنان در مورد Hooks رخ می‌دهد.

با این حال روش مشابه componentDidMount برای استفاده از قلاب‌های ری‌اکت، بهره‌گیری از React.useEffect است، زیرا پس از این رندرینگ کامپوننت‌ها پایان یافت اجرا می‌شود. اگر از React.useRef برای انتساب مقدار به مقدار mount-شده استفاده کنید، می‌توانید همان نتیجه مثال کامپوننت کلاسی را به دست آورید:

مثال دیگری از استفاده خوب از این حالت، ردگیری آخرین تغییرات بدون ایجاد رندر مجدد است و با استفاده همزمان با React.useMemo به دست می‌آید:

بدین ترتیب در صورتی که ref props تغییر یافته و تعریف شده باشد، تابع جدیدی ایجاد خواهد شد. این بدان معنی است که ری‌اکت، ref فورک شده قدیمی را با null فراخوانی می‌کند و ref فورک شده جدید با ref جاری فراخوانی می‌شود. از آنجا که از React.useMemo استفاده می‌کنیم، ref-ها تا زمانی که prop-های مربوطه‌ی refA یا refB تغییر یابند، در حافظه می‌مانند و در طی این فرایند پاکسازی طبیعی رخ می‌دهد.

5. سفارشی‌سازی عناصر وابسته به عناصر دیگر با React.useRef

React.useRef کاربردهای مفید مختلفی دارد که شامل انتساب خودش به ref prop در گره‌های ری‌اکت می‌شود:

اگر بخواهیم موقعیت مختصات عنصر div را به دست آوریم، این مثال کافی است. با این حال اگر عنصر دیگر، جایی در اپلیکیشن بخواهد موقعیت‌های خود را در آن زمان که position تغییر می‌یابد یا نوعی منطق مختصات اعمال می‌شود، به‌روزرسانی کند، بهترین روش این است که این کار را با استفاده از ref callback function pattern انجام دهیم.

زمانی که از الگوی تابع callback استفاده می‌کنیم، یا یک وهله از کامپوننت ری‌اکت به دست می‌آید یا عنصر HTML DOM به عنوان آرگومان نخست بازگشت می‌یابد. مثال زیر صرفاً یک نمونه ساده از حالتی را نشان می‌دهد که setRef تابع callback اعمال شده روی یک ref prop است. چنان که می‌بینید درون setRef امکان انجام هر کاری وجود دارد و این وضعیت عکس به‌کارگیری مستقیم نسخه React.useRef روی عنصر DOM است:

6. کامپوننت‌های مرتبه بالاتر

یک الگوی رایج در جاوا اسکریپت ساده، ایجاد تابع‌های قدرتمند با قابلیت استفاده مجدد به صورت «تابع‌های مرتبه بالاتر» (higher-order function) است. از آنجا که React در نهایت خود همان جاوا اسکریپت است، می‌توان از تابع‌های مرتبه بالاتر درون ری‌اکت نیز استفاده کرد.

در مورد کامپوننت‌های با قابلیت استفاده مجدد، این ترفند به صوت استفاده از «کامپوننت‌های مرتبه بالاتر (higher-order components) است. یک کامپوننت مرتبه بالاتر، تابعی است که یک کامپوننت به عنوان آرگومان می‌گیرد و یک کامپوننت بازگشت می‌دهد.

همان طور که می‌توان از تابع‌های مرتبه بالاتر برای جداسازی منطق و اشتراک آن میان تابع‌های دیگر در اپلیکیشن استفاده کرد، کامپوننت‌های مرتبه بالاتر نیز به ما امکان می‌دهند که منطق را از کامپوننت‌ها جدا کنیم و آن را در میان کامپوننت‌های دیگر به اشتراک بگذاریم.

در ادامه مثالی از یک کامپوننت مرتبه بالاتر معرفی شده است. در این قطعه کد یک کامپوننت مرتبه بالاتر به نام withBorder یک کامپوننت سفارشی می‌گیرد و یک کامپوننت «لایه میانی» (middle layer) بازگشت می‌دهد. سپس هنگامی که والد تصمیم می‌گیرد تا این کامپوننت مرتبه بالاتر را که بازگشت یافته است رندر کند، یک کامپوننت را فراخوانی کرده و props را که از کامپوننت لایه میانی به آن ارسال شده، دریافت می‌کند:

7. رندر کردن props

یکی از ترفندهای خوب که در کتابخانه ری‌اکت استفاده می‌شود، الگوی رندر prop است. این الگو مشابه کامپوننت‌های مرتبه بالاتر است، چون مسئله مشابهی را به صورت اشتراک کد بین کامپوننت‌های مختلف حل می‌کند. رندر props یک تابع عرضه می‌کند که هدف آن ارسال همه چیزهایی است که دنیای بیرون برای رندر کردن فرزندانش نیاز دارد. مقدماتی‌ترین روش برای رندر کامپوننت‌ها در ری‌اکت به صورت زیر است:

هنگام استفاده از رندر کردن props، آن prop که فرزندانش را رندر می‌کند بنا به عرف، render نامگذاری می‌شود:

در این مثال MyComponent نمونه‌ای از یک کامپوننت است. آن را render prop component می‌نامیم، زیرا render را به عنوان یک prop افشا کرده و آن را برای رندر کردن فرزندانش فراخوانی می‌کند.

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

8. Memoize

یکی از مهم‌ترین نکته‌هایی که هر توسعه‌دهنده ری‌اکت باید بداند، شیوه بهینه‌سازی عملکرد کامپوننت‌هایی مانند React.memo است. این کار می‌تواند به جلوگیری از برخی خطاهای بد، مانند حلقه‌های نامتناهی که موجب از کار افتادن اپلیکیشن در زمان اجرا می‌شود کمک کند. برای آشنایی با این مفهوم پیشنهاد می‌کنیم این صفحه‌های مستندات ری‌اکت را مطالعه کنید:

  • React.memo (+)
  • React.useCallback (+)
  • React.PureComponent (+)
  • Optimizing performance (+)

بدین ترتیب به پایان این مقاله می‌رسیم. امیدواریم از مطالعه آن بهره آمورشی لازم را برده باشید.

اگر این مطلب برای شما مفید بوده است، آموزش‌های زیر نیز به شما پیشنهاد می‌شوند:

==

«میثم لطفی» دانش‌آموخته ریاضیات و شیفته فناوری به خصوص در حوزه رایانه است. وی در حال حاضر علاوه بر پیگیری علاقه‌مندی‌هایش در رشته‌های برنامه‌نویسی، کپی‌رایتینگ و محتوای چندرسانه‌ای، در زمینه نگارش مقالاتی با محوریت نرم‌افزار نیز با مجله فرادرس همکاری دارد.

آیا این مطلب برای شما مفید بود؟

نظر شما چیست؟

نشانی ایمیل شما منتشر نخواهد شد. بخش‌های موردنیاز علامت‌گذاری شده‌اند *