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

استفاده از Functional کامپوننت‌ها

استفاده از class کامپوننت‌ها در React قدیمی شده است. در ادامه دلایل اصلی در مورد اینکه چرا باید از Functional کامپوننت‌ها برای برنامه‌های React خود استفاده کنیم را بررسی کرده‌ایم.

چرا Functional کامپوننت‌ها؟

هوک یک تابع ویژه است که به ما اجازه می‌دهد تا به ویژگی‌های React در Functional کامپوننت‌ها متصل شویم.

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

باید به این نکته توجه کنیم که React همچنان از class کامپوننت‌ها پشتیبانی می‌کند، درنتیجه لازم نیست آن‌ها را در Functional کامپوننت‌ها بازنویسی کنیم.

import React, { useState } from "react";

const YesNoButtonComponent = () => {
  const [button, setButton] = useState("");

  const onButtonPress = (buttonName) => {
    setButton(buttonName);
    console.log(buttonName);
  };

  return (
    <div>
      <button onClick={() => onButtonPress("Yes")}>Yes</button>
      <button onClick={() => onButtonPress("No")}>No</button>
     </div>
  );
};

مثال بالا یک Functional کامپوننت‌ با استفاده از هوک useState است.

تجزیه کامپوننت‌ها

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

چه زمانی باید کامپوننت‌ها را تجزیه کنیم؟

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

اهمیت تایپ اسکریپت

در ادامه چند دلیل اصلی وجود دارد که چرا فکر می‌کنیم تایپ اسکریپت بسیار مهم و تاثیرگذار است:

type HeadingProps = {
  title: string;
  bold: boolean;
}

export const Heading = ({ title, bold }: HeadingProps) => {
  return (
    <div>
      {bold ? "Bold Title: " : "Regular Title: "}
      {title}
    </div>
  );
};

در مثال بالا می‌توانیم تایپ اسکریپت را در عمل مشاهده کنیم. کامپوننت Headingپراپس titleو نوع بولد HeadingPropsرا می‌پذیرد. هر زمان که کامپوننت Headingرا فراخوانی کنیم، باید تمام props را با انواع مناسب به آن منتقل کنیم. اگر یک props را از دست بدهیم و یا از نوع نادرست ارسال کنیم، IDE برای ما یک خطا مطابق زیر ایجاد می‌کند.

const Heading = ({ title, bold }: HeadingProps) => JSX.Element
-------------------------------------------------------------------
Type '{}' is missing the following properties from type 'HeadingProps': title, bold ts(2739)

این موضوع هنگام توسعه کامپوننت‌های React بسیار عالی است زیرا باعث دریافت بازخورد فوری هنگام کدنویسی می‌شود.

شروع کار با local state

در بسیاری از مواقع زمانی که پروژه‌های React شروع می‌شوند، توسعه‌دهندگان بلافاصله فکر می‌کنند که به نوعی به یک کتابخانه مدیریت state خارجی نیاز دارند. زمانی که تیم‌ها شروع به ساختن یک برنامه React می‌کنند دیدن راه‌اندازی Redux/MobX/XState یا کتابخانه‌های مشابه غیرمعمول نیست.

توصیه‌ای که می‌شود این است که برای ساخت برنامه React با local state شروع کنیم و با رشد برنامه خود سایر تصمیمات مربوط به مدیریت state را بگیریم. اغلب اوقات برنامه ما ممکن است واقعاً به راه‌حل‌های پیچیده برای مدیریت state نیاز نداشته باشد. پس چرا حجم زیادی از کتابخانه‌ها را اضافه کنیم در صورتی که می‌توانیم از آن‌ها استفاده نکنیم؟

دنباله‌ای از کارها که هنگام رشد برنامه خود بهتر است آن را دنبال کنیم:

  1. ابتدا با local state شروع کنیم: وقتی شروع به ساختن برنامه خود کردیم، state را برای هر کامپوننت به شکل local نگه داریم که این موضوع در اکثر مواقع می‌تواند کافی باشد. برای مدیریت state از هوک useState استفاده کنیم.
  2. انتقال state از طریق props: اگر کامپوننت child نیاز به دسترسی به state از طریق کامپوننت parent داشته باشد، می‌توانیم آن را به کمک props از parent به child منتقل کنیم.
  3. Lift state up: ممکن است شرایطی وجود داشته باشد که یک کامپوننت غیر child نیاز به دسترسی به داده‌ها از کامپوننت دیگری داشته باشد. در این سناریو می‌توانیم از مفهوم lifting state up استفاده کنیم. یعنی این که اشتراک‌گذاری state با انتقال آن به نزدیک‌ترین جد مشترک کامپوننتی که به آن نیاز دارند انجام می‌شود.
  4. استفاده از context: context برای به اشتراک گذاری داده‌هایی که برای درختی از کامپوننت‌های React، سراسری هستند طراحی شده است. context معمولاً برای داده‌هایی مانند اطلاعات دموگرافیک، theme و غیره استفاده می‌شود که اکثر کامپوننت‌ها به آن‌ها نیاز دارند.
  5. اگر مواردی که در بالا ذکر شد کافی نبود سراغ مدیریت state خارجی می‌رویم: اگر همه روش‌های فوق را امتحان کردیم و state برنامه ما همچنان در حال رشد بود و فکر می‌کنیم می‌تواند استفاده از یک راه‌حل مدیریت state خارجی مفید باشد از آن استفاده می‌کنیم. گزینه‌های زیادی مانند Redux، MobX، XState و غیره وجود دارد که می‌توانیم از آن‌ها در برنامه خود به‌کار بگیریم.

تست کد

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

Unit Tests

Jest محبوب‌ترین فریم‌ورک تست برای unit testها است. فریم‌ورک‌های دیگری مانند Mocha نیز وجود دارد که می‌توانیم از آن‌ها هم استفاده کنیم. unit test ابتدایی‌ترین شکل تست است که این امکان را به ما می‌دهد تا کوچک‌ترین واحدهای کد خود را مورد آزمایش قرار دهیم.

Component Tests

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

Automated End to End Tests

این نوع تست اساساً برنامه را به طور کلی مورد بررسی قرار می‌دهد. این فریم‌ورک شبیه‌سازی می‌کند که کاربر چگونه روی برنامه کلیک کرده و آن را در مرورگر آزمایش می‌کند. محبوب‌ترین و آسان‌ترین فریم‌ورک برای تست end to end جاوااسکریپت (یا هر چیزی که روی مرورگر اجرا می‌شود) Cypress است.

جمع‌بندی

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