Error Boundaries در React – بخش ۱

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

معرفی مرزهای ارور

یک ارور جاوا اسکریپت در بخشی از رابط کاربری نباید کل برنامه را مختل کند. برای حل این موضوع برای کاربران React، در نسخۀ ۱۶ ری‌اکت، مفهوم جدیدی از مرزهای ارور معرفی شد.

مرزهای ارور، کامپوننت‌های React هستتند که ارورهای جاوا اسکریپت را در هر جایی از درخت کامپوننت child که باشند، گرفته، آنها را ثبت کرده و یک رابط کاربری fallback را به جای درخت کامپوننتی که خراب شده است را نشان می‌دهد. مرزهای ارور، در حین رندر شدن، در متد چرخۀ زندگی، و در constructor های پایین‌تر از آنها در کل درخت، ارورها را می‌گیرند.

نکته: مرزهای ارور، ارورهای مربوط به موارد زیر را نمی‌گیرند:

  • کنترل کنندۀ رویدادها (بیشتر بدانید)
  • کدهای ناهمگام (مانند callback های مربوط به setTimeout یا requestAnimationFrame)
  • رندر شدن از سمت سرور
  • ارورهای رفته به خود مرزهای ارور (به جای children آن)

یک کامپوننت class اگر یک متد چرخۀ زندگی جدید به نام componentDidCatch(error, info) را تعریف کند، یک مرز ارور خواهد شد:

class ErrorBoundary extends React.Component {
  constructor(props) {
    super(props);
    this.state = { hasError: false };
  }

  componentDidCatch(error, info) {
    // Display fallback UI
    this.setState({ hasError: true });
    // You can also log the error to an error reporting service
    logErrorToMyService(error, info);
  }

  render() {
    if (this.state.hasError) {
      // You can render any custom fallback UI
      return <h1>Something went wrong.</h1>;
    }
    return this.props.children;
  }
}

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

<ErrorBoundary>
  <MyWidget />
</ErrorBoundary>

متد componentDidCatch() مانند بلاک catch {} جاوا اسکریپت عمل می‌کند اما برای کامپوننت‌ها. فقط کامپوننت‌های class می‌توانند مرزهای ارور شوند. در عمل، اکثر اوقات شما می‌خواهید یک بار یک کامپوننت مرز ارور یا تعریف کنید و در طول برنامۀ خود از آن استفاده کنید.

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

پارامترهای componentDidCatch

error یک اروری است که پرتاب شده است.

info آبجکتی با کلید componentStack است. Property نیز اطلاعات راجع به componentStack را حین پرتاب دارد.

//...
componentDidCatch(error, info) {

  /* Example stack information:
     in ComponentThatThrows (created by App)
     in ErrorBoundary (created by App)
     in div (created by App)
     in App
  */
  logComponentStackToMyService(info.componentStack);
}

//...

Live Demo

این مثال که شامل تعریف و استفاده از مرزهای ارور با نسخۀ ۱۶ ری‌اکت است را ببینید.

 

مرزهای ارور را کجا قرار دهیم

مقیاس و جزئیات موجود در مرزهای ارور به شما بستگی دارد. ممکن است شما از کامپوننت‌های سطح بالا برای نمایش پیغام “چیزی اشتباه شده است” به کاربر، استفاده کنید، درست مانند فریم‌ورک‌های سمت سروردر کنترل کرش‌ها (crash). همچنین ممکن است از ویجت‌های تکی در مرزهای ارور استفاده کنید تا از کرش بقیه قسمت‌های برنامه محافظت کنید.

رفتار جدید برای ارورهای گمشده

این تغییر پیامد مهمی دارد. در نسخۀ ۱۶ ری‌اکت، ارورهایی که توسط هیچ مرز اروری گرفته نشده‌اند، باعث انحلال (unmounting) کل درخت کامپوننت React می‌شوند.

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

این تغییر یعنی با کوچ کردن شما به نسخۀ ۱۶ ری‌اکت، احتمالا شما خرابی‌های موجود در برنامۀ خود را که قبلا نسبت به آن بی‌توجه بودید، برملا خواهید کرد. اضافه کردن مرزهای ارور به شما اجازه می‌دهد تجربۀ کاربری بهتری را وقتی چیز اشتباهی رخ می‌دهد، فراهم سازید.

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

همچنین شما به استفاده از سرویس گزارش ارور JS ترغیب می‌کنیم (یا اینکه خودتان بسازید) در نتیجه می‌توانید در مورد استثنائات کنترل نشده نیز بدانید و وقتی در محصول شما بوجود آمدند آنها را اصلاح کنید.

** در مقاله بعدی به ادامه مبحث ( Error Boundaries ) در React خواهیم پرداخت. مشاهده بخش ۲

1 Star2 Stars3 Stars4 Stars5 Stars (2 votes, average: 5٫00 out of 5)
Loading...
counter customizable free hit