۲۹ شهریور ۱۴۰۳

Techboy

اخبار و اطلاعات روز تکنولوژی

نحوه رسیدگی به خطاها در React

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

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

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

انواع خطای واکنش

می‌توانیم خطاهای برنامه React را به طور کلی به دو نوع و مدیریت خطا را به دو جنبه تقسیم کنیم.

دو نوع خطای React:

  • خطاهای جاوا اسکریپت: اینها خطاهای معمولی جاوا اسکریپت هستند که در قسمت کد یک جزء رخ می دهند.
  • خطاهای رندر: اینها خطاهایی هستند که توسط موتور رندر ایجاد می شوند و از نشانه گذاری ظاهر می شوند.

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

خطاهای جاوا اسکریپت در کد رخ می‌دهند و می‌توانند با بلوک‌های استاندارد try/catch کنترل شوند، در حالی که خطاهای رندر در قالب‌های view رخ می‌دهند و توسط مرزهای خطای React مدیریت می‌شوند. می‌توانیم مرزهای خطا را به‌عنوان بلوک‌های try/catch در نشانه‌گذاری الگو در نظر بگیریم.

در هر دو حالت دو جنبه مدیریت خطا وجود دارد:

  • نمایش اطلاعات برای کاربر
  • ارائه اطلاعات به برنامه‌نویس

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

مرزهای خطای واکنش

متمایزترین و خاص ترین نوع رسیدگی به خطا، چیزی است که به عنوان مرزهای خطا شناخته می شود. این ویژگی در React 16 معرفی شده است و به شما امکان می دهد اجزایی را تعریف کنید که به عنوان مکانیزم های خطایابی برای درخت مؤلفه زیر آنها عمل می کنند.

مایکروسافت از پیشرفت های زبان C# 12 رونمایی کرد

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

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

این دو روش componentDidCatch() و getDerivedStateFromError() هستند که ثابت است. در هر دو مورد، هدف اصلی به‌روزرسانی وضعیت مؤلفه است تا بتواند به خطاهای وارد شده از موتور React پاسخ دهد.

componentDidCatch()

روش componentDidCatch() عادی است و می‌تواند وضعیت مؤلفه را به‌روزرسانی کند، و همچنین اقداماتی مانند برقراری تماس سرویس با یک پایانه گزارش‌دهنده خطا را انجام دهد. فهرست ۱ استفاده از این روش را به ما نشان می دهد.


componentDidCatch(error, errorInfo) {
    errorService.report(errorInfo);
    this.setState({ error: error, errorInfo: errorInfo })
  }

در فهرست ۱، تابع اولیه تضمین می‌کند که وضعیت مؤلفه خطا رخ داده است و اطلاعات مربوط به آن خطا را در اختیار شما قرار می‌دهد. توجه داشته باشید که این componentDidCatch() به زمان اجرا دسترسی دارد.

getDerivedStateFromError()

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


static getDerivedStateFromError(error) {
  return { isError: true };
}

فهرست ۲ یک شی را با یک پرچم خطا برمی گرداند که می تواند توسط مؤلفه در ارائه آن استفاده شود. ما می‌توانیم با ساختن اشیاء خطای پیچیده‌تر، نیازهای دقیق‌تری را برطرف کنیم.

پردازش بر اساس خطا

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


render() {
  if (this.state.error && this.state.errorInfo) {
    return (
      <div>
        <p>Caught an Error: {this.state.error.toString()}</p>
        <div>
          {this.state.errorInfo.componentStack}
        </div>
      </div>
    );
  } else {
    return this.props.children;
  }
}

از فهرست ۳ می‌توانید ببینید که عملکرد پیش‌فرض مؤلفه رندر کردن فرزندان آن است. یعنی یک جزء عبوری ساده است. اگر حالت خطا پیدا شود (مانند فهرست ۱ یا فهرست ۲)، نمای جایگزین ارائه می شود. در حالی که رفتار پیش‌فرض رندر کردن رابط است، یک حالت خطا یک مسیر جایگزین را فراخوانی می‌کند، چیزی شبیه بلوک catch.

Visual Studio Code 1.76 در قابلیت استفاده، pytest می درخشد

استفاده از مؤلفه ErrorBoundary

اکنون عناصر ضروری یک مؤلفه رسیدگی به خطا را در React مشاهده کرده اید. استفاده از کامپوننت بسیار ساده است، همانطور که در لیست ۴ نشان داده شده است.


<Parent>
  <ErrorBoundary>
    <Child><Child/>
  </ErrorBoundary>
</Parent>

در فهرست ۴، هر گونه خطای رندر در رندر جایگزین مولفه را آغاز می کند. می‌توانید ببینید که اجزای مرز خطا به‌عنوان نوعی بلوک تلاش/گرفتن اعلامی در نما عمل می‌کنند. همه فرزندان نیز به حباب می‌شوند، مگر اینکه در طول مسیر توسط مرز خطای دیگری گیر بیفتند – همچنین مشابه رفتار امتحان/گرفتن.

خطاهای جاوا اسکریپت

خطاهای جاوا اسکریپت مانند جاوا اسکریپت استاندارد با قرار دادن کد در بلوک‌های try/catch مدیریت می‌شوند. این به خوبی قابل درک است و عالی کار می کند، اما چند نظر در زمینه یک React UI وجود دارد.

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

خطاهای شبکه

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


let response = await fetch(process.env.REACT_APP_API + 
'/api/describe?_id='+this.state.projectId, {
        headers: { "Authorization": this.props.userData.userData.jwt },
        method: 'GET',
      });
      if (response.ok){
        let json = await response.json();
        console.info(json);
        this.setState({ "project": json});
      } else {
        console.error("Problem: " + response);
        throw new Error(“Problem fetching user info”, response);
      }

نکته فهرست ۵ استفاده از کدهای وضعیت استاندارد HTTP برای تعیین وضعیت خطای درخواست شبکه است. (گاهی اوقات استفاده از یک فیلد سفارشی «وضعیت» وسوسه انگیز است.) در این حالت، خطا با علامت زدن response.ok شناسایی می‌شود، و سپس اگر خطایی وجود داشته باشد، یک خطای جدید با پرتاب. در این مورد، انتظار داریم که یک کنترل کننده شکار با این وضعیت برخورد کند.

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

بررسی خطا در عمل

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

بنابراین این به شما نگاهی به کد و رفتار چندین حالت خطای احتمالی می‌دهد:

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

این مثال‌ها ارزش بررسی دارند، زیرا همه عناصر کاری مرزهای خطا را در یک بسته با اندازه بیت به شما ارائه می‌دهند.

ممکن است بررسی این نمونه مرزهای خطای CodePen در React 16 نیز مفید باشد. .

نتیجه گیری

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

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

همانطور که دیدیم، ایده اصلی این است که شما یک مؤلفه ایجاد کنید که به صورت مشروط بر اساس حالت خطا ارائه شود. دو راه برای انجام این کار وجود دارد: روش componentDidCatch() یا روش ثابت getDerivedStateFromError().