چگونه در React، کد بهتری بنویسیم؟

گردآوری و تالیف : عرفان کاکایی
تاریخ انتشار : 29 مرداد 1397
دسته بندی ها : جاوا اسکریپت

React، ساخت رابط‌های کاربری تعاملی را آسان‌تر می‌کند. برای هر state در برنامه خود، viewهای ساده‌ای طراحی کنید و React هر زمان که داده‌های شما تغییر کنند، خودش کامپوننت‌ها مناسب را بروزرسانی کرده و رندر می‌کند.

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

بیایید درباره Linting (خطایابی) صحبت کنیم

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

import react from 'react';
/* Other imports */

/* Code */

export default class App extends React.Component {
  render() {
    const {userIsLoaded, user} = this.props;
    if (!userIsLoaded) return <Loader />;
    
    return (
      /* Code */
    )
  }
}

قطعه کد بالا را در نظر داشته باشید. فرض کنید که می‌خواهید در تابع render() خود، به ویژگی‌ای به نام this.ptops.hello اشاره کنید. خطایاب شما سریعا قرمز شده و می‌گوید:

'hello' is missing in props validation (react/prop-types)

خطایاب می‌تواند از بهترین روند در React مطلع شود و درک کد شما را شکل دهد. در مدت زمانی کوتاه، دیگر در کد خود اشتباه نخواهید کرد.

propTypeها و defaultPropها

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

static propTypes = {
  userIsLoaded: PropTypes.boolean.isRequired,
  user: PropTypes.shape({
    _id: PropTypes.string,
  )}.isRequired,
}

در اینجا، اگر بخواهیم بگوییم که userIsLoaded نیاز نیست، باید این را به کد خود اضافه کنیم:

static defaultProps = {
 userIsLoaded: false,
}

پس هر وقت یک PropType داریم که در کامپوننت ما استفاده شده است، باید یک propType برایش تعیین کنیم. به این صورت، باید به React بگوییم که userIsLoaded همیشه قرار است یک مقدار Boolean باشد.

و دوباره، اگر بخواهیم بگوییم که userIsLoaded نیاز نیست، باید یک ویژگی پیش‌فرض داشته باشیم. اگر هم نیاز است، دیگر نیازی نییست برایش یک ویژگی پیش‌فرض تعریف کنیم. گرچه، این قانون همچنین می‌گوید که نباید یک propType مبهم مانند یک آبجکت یا یک آرایه داشته باشیم.

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

باید همیشه مطمئن باشید که propTypes و defaultProps بر روی هر کامپوننت که از props استفاده می‌کند، راه‌اندازی شده باشد.

هر لحظه که این ویژگی‌ها، داده‌هایی که انتظار دارند را دریافت نکنند، error log شما به شما می‌گوید که یا در حال انتقال نادرست یک چیز هستید، یا یک چیزی که آن ویژگی انتظار دارد، در آنجا وجود ندارد؛ و در نتیجه خطایابی را بسیار آسان‌تر می‌کند.

نکته

بر خلاف دیگر نسخه‌های React، propTypeها دیگر در داخل React وجود ندارند و باید آن‌ها را به صورت جداگانه به پروژه خود به عنوان یک Dependency اضافه کنید.

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

export default class Profile extends PureComponent {
  static propTypes = {
    userIsLoaded: PropTypes.bool,
    user: PropTypes.shape({
      _id: PropTypes.string,
    }).isRequired,
  }

  static defaultProps = {
    userIsLoaded: false,
  }

  render() {
    const { userIsLoaded, user } = this.props;
    if (!userIsLoaded) return <Loaded />;
    return (
      <div>
        <div className="two-col">
          <section>
            <MyOrders userId={user.id} />
            <My Downloads userId={user._id} />
          </section>
          <aside>
            <MySubscriptions user={user} />
            <MyVotes user={user} />
          </aside>
        </div>
        <div className="one-col">
          {isRole('affiliate', user={user._id} &&
            <MyAffiliateInfo userId={user._id} />
          }
        </div>
      </div>
    )
  }
}

در اینجا، کامپوننتی به نام Profile داریم. در داخل این کامپوننت نیز، کامپوننت‌های دیگری منند MyOrder و MyDownloads داریم. حال از آنجایی که داده‌ها را از یک جا (user) می‌گیریم، می‌توانستیم تمام این کامپوننت‌ها را به صورت خطی بنویسیم، و تمام این کامپوننت‌های کوچک را تبدیل به یک کامپوننت بزرگ کنیم.

با این که قوانین سختی درباره این که چه زمانی کد خود را به یک کامپوننت منتقل کنید وجود ندارد، از خود بپرسید:

  • آیا عملکرد کد شما در حال غافلگیر کننده شدن است؟
  • آیا نمایانگر کار خود است؟
  • آیا قرار است از کد خود مجددا استفاده کنید؟

اگر پاسخ هر کدام از این سوالات «بله» است، پس باید کد خود را به یک کامپوننت منتقل کنیم.

در نظر داشته باشید که هیچ کس دوست ندارد یک کامپوننت 200 - 300 خطی را در کد شما ببیند.

کامپوننت، PureComponent و کامپوننت تابعی بدون state

برای یک توسعه دهنده React، این که بداند چه زمانی از Component، چه زمانی از PureComponent و چه زمانی از کامپوننت تابعی بدون state در کد خود استفاده کند، بسیار مهم است.

شاید متوجه شده باشید که در قطعه کد بالا، به جای تعریف Profile به جای یک کامپوننت، آن را به عنوان یک PureComponent تعریف کرده‌ایم.

در ابتدا، بیایید یک کامپوننت تابعی بدون state را بررسی کنیم.

کامپوننت تابعی بدون state

const Billboard = () => (
  <ZoneBlack>
    <Heading>React</Heading>
    <div className="billboard_product">
      <Link className="billboard_product-image" to="/">
        <img alt="#" src="#">
      </Link>
      <div className="billboard_product-details">
        <h3 className="sub">React</h3>
        <p>Lorem Ipsum</p>
      </div>
    </div>
  </ZoneBlack>
);

کامپوننت‌های تابعی بدون state یکی از پر استفاده‌ترین انواع کامپوننت‌ها هستند. آن‌ها روش خوب و مختصری برای ساخت کامپوننت‌هایی که از هیچگونه state، ref یا متدهای lifecycle استفاده نمی‌کنند، فراهم می‌کنند.

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

به صورت ساده‌تر، کامپوننت‌های تابعی بدون state فقط توابعی هستند که JSX را بر می‌گردانند.

PureComponentها

معمولا وقتی که یک کامپوننت، یک ویژگی را در خود دریافت می‌کند، React آن کامپوننت را مجددا رندر می‌کند. اما گاهی اوقات، یک کامپوننت propهایی دریافت می‌کند که واقعا تغییر نکرده‌اند، اما React همچنان یک رندر مجدد را انجام می‌دهد.

استفاده از PureComponent، به شما در جلوگیری از این رندر مجدد کمک می‌کند. برای مثال، اگر یک prop، یک رشته یا یک boolean است که تغییر می‌کند، یک PureComponent آن را تشخیص می‌دهد؛ اما اگر یک ویژگی در داخل یک آبجکت تغییر می‌کند، توسط PureComponent مجددا رندر نخواهد شد.

پس از کجا باید بدانیم که React‌ در حال انجام یک رندر بیهوده است؟ می‌توانید نگاهی به پکیج شگفت‌انگیز Why Did You Update داشته باشد. این پکیج زمانی که یک رندر بیهوده انجام شود، در کنسول به شما اخطار می‌دهد.

وقتی که یک رندر بیهوده را تشخیص داده‌اید، می‌توانید از PureComponent به جای Component استفاده کنید تا از این اتفاق جلوگیری کنید.

از React Dev Tools استفاده کنید

استفاده از React Dev Toold (ابزار توسعه React) نیز می‌تواند در توسعه بهتر به شما کمک کند. اگر قبلا از React استفاده کرده باشید، به احتمال زیاد کنسول شما استفاده از آن‌ها را پیشنهاد کرده است. ابزار توسعه React برای تمام مرورگرهای معروف مانند Chrome و Firefox در دسترس هستند.

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

از بیانیه‌های شرطی خطی استفاده کنید

ممکن است این ایده عجیب به نظر برسد، اما استفاده از بیانیه‌های شرطی خطی، کد React شما را مرتب می‌کند.

نگاهی به این قطعه کد داشته باشید:

<div className="one-col">
  {isRole('affiliate', user._id) &&
    <MyAffiliateInfo userId={user._id} />
  }
</div>

در اینجا، یک تابع اساسی را فراخوانی کرده‌ام که بررسی می‌کند که یک کاربر affiliate (وابسته) است یا نه، و به دنبالش کامپوننتی به نام <MyAffiliateInfo/> وجود دارد.

نکته خوب درباره آن این است که:

  • مجبور نبودم که یک تابع جداگانه بنویسم.
  • مجبور نبودم که یک بیانیه if دیگر در تابع رندر خود بنویسم.
  • مجبور نبودم که یک لینک به جای دیگری از کامپوننت خود ایجاد کنم.

نوشتن بیانیه‌های شرطی خطی کاملا ساده است. با نوشتن یک بیانیه شرطی شروع می‌کنید. سپس، بیانیه شرطی را با استفاده از && به <MyAffiliateInfo /> لینک می‌کنید. به این صورت، کامپوننت مورد نظر فقط وقتی که بیانیه شرطی مقدار true را برگرداند، رندر می‌شود.

در هر کجا که امکانش هست، از قطعه کدهای موجود در کتابخانه‌ها استفاده کنید

یک ویرایشگر کد (که من از VS Code استفاده می‌کنم) را باز کرده و یک فایل .js بسازید.

در داخل فایل، وقتی که rc را تایپ می‌کنید، چنین چیزی خواهید دید:

با فشردن کلید enter، سریعا این را دریافت خواهید کرد:

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

خلاصه کلی

  1. یک خطایابی خوب راه‌اندازی کنید.
  2. از propTypeها و defaultPropها استفاده کنید.
  3. بدانید که چه زمانی باید یک کامپوننت جدید بسازید.
  4. بدانید که کی باید از Component، کی از PureComponent و کی از کامپوننت تابعی بدون state استفاده کنید.
  5. از ابزار توسعه React (React Dev Tools) استفاده کنید.
  6. از بیانیه شرطی خطی در کد خود استفاده کنید.
  7. از کتابخانه‌های قطعه کد استفاده کنید تا از هدر رفتن زمان بر روی کد boilerplate جلوگیری کنید.
  8. بدانید که React چگونه در React Internals کار می‌کند.

منبع

مقالات پیشنهادی

مجموعه‌ای از بهترین کد ادیتورهای 2018

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

۱۰ تکنیک کدنویسی درست که هر فرد کدنویسی باید بداند

شیوه نمایش درست به اندازه محتوایی که آن را نمایش می دهید روی کیفیت تاثیر می گذارد. به گمانم بتوانیم این سخن را در برنامه نویسی کامپیوتر نیز به کار ببر...

چگونه کد خود را خواناتر کنیم؟

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

چگونه از خودتان طراح بهتری بسازید؟

به شخصه من طرفدار کارا و مؤثر بودن هستم. در حالیکه این ویژگی الزاما حالت کسل کننده ای در جمع دوستان نیست اما این حالت در یک روز کاری به من بیشتر احساس...