Error Boundary — چیست، کامپوننت React Native و مدیریت خطا

نویسنده: IT Sectr منتشر شده: 2026-05-27 زمان مطالعه: 8 دقیقه

Error Boundary کامپوننت React است که خطاهای JavaScript را در درخت کامپوننت‌های فرزند خود می‌گیرد و به جای صفحه crash یک رابط جایگزین نمایش می‌دهد. در زمینه React Native از سقوط کامل برنامه در خطاهای غیربحرانی رندر جلوگیری می‌کند. طبق React Documentation, 2024، error boundary خطاها را در متدهای render، lifecycle-hookها و سازنده‌های کامپوننت‌های فرزند می‌گیرد و به برنامه اجازه ادامه کار می‌دهد. در React Native این امر بسیار حیاتی است، زیرا برنامه موبایل با F5 بارگذاری مجدد نمی‌شود — کاربر کل نشست خود را از دست می‌دهد.

نکات اصلی

  • Error Boundary — کامپوننت React برای گرفتن خطاهای رندر در درخت فرزند
  • ComponentDidCatch — متد چرخه حیاتی که خطا و اطلاعات پشته را دریافت می‌کند
  • Fallback UI — رابط جایگزین نمایش داده شده به جای کامپوننت خراب
  • React Native از Error Boundary برای جلوگیری از سقوط کامل برنامه استفاده می‌کند
  • محدودیت — Error Boundary خطاهای کد ناهمگام و event-handlerها را نمی‌گیرد

Error Boundary چیست

Error Boundary مکانیزم React برای تنزل تدریجی (graceful degradation) در خطاهای رندر است. در React 16 (2017) به عنوان کامپوننت wrapper معرفی شد که یکی از دو متد چرخه حیات را پیاده‌سازی می‌کند: static getDerivedStateFromError یا componentDidCatch. Error Boundary به کاربر اجازه می‌دهد به جای صفحه سفید خالی یا سقوط کامل برنامه، یک پیام معنادار ببیند.

Error Boundary چگونه پدید آمد

پیش از React 16، هر خطای مدیریت‌نشده در render منجر به سقوط کل برنامه با حذف کل درخت DOM می‌شد. در برنامه‌های وب این به معنای صفحه سفید خالی و در React Native سقوط کامل برنامه با بازگشت به صفحه اصلی بود. تیم React Error Boundary را به عنوان معادل catch-block برای UI اعلامی معرفی کرد و این مفهوم را از رویکرد «بگذار سقوط کند» در زبان Erlang به عاریت گرفت.

اهمیت برای React Native

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

Error Boundary در React Native چگونه کار می‌کند

Error Boundary در سطح درخت React کار می‌کند. وقتی کامپوننت فرزند در render یا lifecycle خطا می‌اندازد، React کل درخت را حذف نمی‌کند، بلکه کنترل را به نزدیک‌ترین Error Boundary بالاتر در سلسله‌مراتب می‌دهد. Boundary متد getDerivedStateFromError را فراخوانی می‌کند، state.hasError = true تنظیم می‌کند و به جای شاخه خراب کامپوننت‌ها fallback UI رندر می‌کند.

typescript
import React, { Component, ErrorInfo, ReactNode } from "react"

interface Props {
    children: ReactNode
    fallback?: ReactNode
}

interface State {
    hasError: boolean
    error?: Error
}

class ErrorBoundary extends Component<Props, State> {
    constructor(props: Props) {
        super(props)
        this.state = { hasError: false }
    }

    static getDerivedStateFromError(error: Error): State {
        return { hasError: true, error }
    }

    componentDidCatch(error: Error, info: ErrorInfo) {
        console.error("توسط boundary گرفته شد:", error)
        Crashlytics.recordException(error)
    }

    render() {
        if (this.state.hasError) {
            return this.props.fallback || <FallbackUI />
        }
        return this.props.children
    }
}

getDerivedStateFromError وضعیت را برای رندر fallback UI تنظیم می‌کند — این یک متد ایستا است که در مرحله رندر قبل از تثبیت تغییرات فراخوانی می‌شود. componentDidCatch در مرحله تثبیت اجرا می‌شود و برای عوارض جانبی طراحی شده است: ثبت وقایع، ارسال crash-report به Crashlytics، تحلیل. دو متد مسئولیت را بین مدیریت وضعیت UI و عوارض جانبی تقسیم می‌کنند.

ایجاد کامپوننت Error Boundary

برای ایجاد Error Boundary باید یک کامپوننت کلاسی با متدهای getDerivedStateFromError و/یا componentDidCatch پیاده‌سازی کنید. کامپوننت‌های تابعی نمی‌توانند Error Boundary باشند — React این قابلیت را فقط برای کامپوننت‌های کلاسی پشتیبانی می‌کند، زیرا دسترسی به متدهای چرخه حیات لازم است. کتابخانه react-error-boundary یک پیاده‌سازی آماده کلاسی با API هوک برای راحتی ارائه می‌دهد.

typescript
// مثال استفاده از Error Boundary در React Native
import { ErrorBoundary } from "react-error-boundary"

const FallbackComponent = ({ error, resetError }: FallbackProps) => (
    <View style={styles.container}>
        <Text>مشکلی پیش آمد</Text>
        <Text>{error.message}</Text>
        <Button title="تلاش مجدد" onPress={resetError} />
    </View>
)

const App = () => (
    <SafeAreaView>
        <ErrorBoundary FallbackComponent={<FallbackComponent />}>
            <UserProfile userId={"123"} />
        </ErrorBoundary>
        <BottomNavigation />
    </SafeAreaView>
)

سطوح wrapper — Error Boundary را می‌توان در سطوح مختلف سلسله‌مراتب قرار داد. یک Boundary سراسری در ریشه برنامه در هر خطایی fallback UI نشان می‌دهد، اما ناوبری همچنان کار می‌کند. چندین Boundary در سطح صفحه به ایزوله کردن خطاها کمک می‌کند: اگر یک صفحه خراب شد، بقیه به طور مستقل به کار خود ادامه می‌دهند. react-error-boundary مکانیزم Reset را از طریق هوک useErrorBoundary ساده می‌کند و امکان بازنشانی وضعیت بدون بارگذاری مجدد را فراهم می‌کند. برای پروژه‌های معمولی، طرح با سه سطح Boundary برای برنامه‌های React Native بهینه در نظر گرفته می‌شود.

بازنشانی وضعیت Error Boundary

پس از وقوع خطا، کاربر می‌تواند دکمه «تلاش مجدد» را فشار دهد که hasError را به false بازنشانی کرده و درخت فرزند را دوباره رندر می‌کند. مکانیزم Reset برای بازیابی قابلیت کار برنامه بدون بارگذاری مجدد مهم است. در react-error-boundary از callback onReset استفاده می‌شود که می‌تواند کش را پاک کند، داده‌ها را دوباره درخواست کند یا وضعیت بالاتر درخت را به‌روزرسانی کند.

محدودیت‌های Error Boundary

Error Boundary خطاهای ناهمگام را نمی‌گیرد — خطاهای setTimeout، setInterval، Promise، async/await. React نمی‌تواند خطاهای خارج از چرخه render و lifecycle-hookها را بگیرد، زیرا آنها در زمینه‌های اجرایی دیگری اجرا می‌شوند. برای خطاهای ناهمگام نیاز به try-catch جداگانه در handlerها یا handler سراسری رویداد unhandledrejection است.

Event-handlerها

خطاهای onClick، onChange و سایر event-handlerها توسط Error Boundary گرفته نمی‌شوند، زیرا خارج از رندر React اجرا می‌شوند. مدیریت خطا برای event-handlerها باید از طریق try-catch داخل خود handler انجام شود. کتابخانه react-error-boundary هوک useErrorHandler را برای ارسال خطاها از event-handlerها به نزدیک‌ترین Boundary ارائه می‌دهد.

رندر سمت سرور و Next.js

Error Boundary در سمت سرور در Next.js یا Gatsby کار نمی‌کند. متدهای getDerivedStateFromError و componentDidCatch در SSR فراخوانی نمی‌شوند، زیرا متدهای چرخه حیات فقط در مرورگر در دسترس هستند. برای خطاهای سرور نیاز به استراتژی جداگانه است: try-catch در getServerSideProps، صفحات fallback error.js (Next.js 13+) یا middleware سراسری.

لایه بومی React Native

در React Native Error Boundary از سقوط در سطح ماژول‌های بومی جلوگیری نمی‌کند. سقوط بومی (segfault، out-of-memory، استثنای بومی) در سطح Objective-C یا Java رخ می‌دهد و به لایه JavaScript نمی‌رسد. برای سقوط‌های بومی به Crashlytics NDK (Android) یا KSCrash (iOS) نیاز است. Error Boundary فقط از لایه JavaScript برنامه React Native محافظت می‌کند.

بهترین روش‌های Error Boundary

Error Boundary را در مرزهای ماژول‌های معنایی قرار دهید: یک Boundary برای هر صفحه، یک Boundary برای ویجت توسعه‌دهنده شخص ثالث، یک Boundary برای فرم پیچیده. این کار خطاها را ایزوله می‌کند و به کاربر اجازه می‌دهد در بقیه بخش‌های برنامه به کار ادامه دهد. Boundary ریشه باید همیشه وجود داشته باشد — برای خطاهای بحرانی در کامپوننت‌های مشترک ناوبری یا providerها. هر Boundary مسئول قطعه رابط خود است و در صورت وقوع خطا روی کامپوننت‌های مجاور تأثیر نمی‌گذارد.

ثبت وقایع و نظارت

همیشه خطا را از طریق componentDidCatch به Crashlytics یا Sentry ارسال کنید. زمینه اضافه کنید: نام صفحه، userId، نسخه برنامه، پارامترهای ناوبری. در Sentry breadcrumbs در دسترس هستند — دنباله اقدامات کاربر قبل از خطا. برای تحلیل فراوانی خطاهای غیربحرانی از داشبوردهای Crashlytics با گروه‌بندی بر اساس issue استفاده کنید.

Fallback UI

از fallback «خالی» استفاده نکنید — یک رابط معنادار ایجاد کنید. مجموعه توصیه‌شده برای React Native: پیام خطا (دوستانه برای کاربر، نه فنی)، دکمه «تلاش مجدد»، لینک پشتیبانی یا چت. از View خالی خودداری کنید — کاربر فکر می‌کند برنامه کاملاً خراب شده و آن را می‌بندد. Fallback باید در طراحی کلی برنامه ادغام شود.

تست Error Boundary

هر Error Boundary را با React Testing Library یا React Native Testing Library تست کنید. یک کامپوننت محرک ایجاد کنید که در زمان رندر خطا می‌اندازد و بررسی کنید که fallback UI نمایش داده می‌شود. برای تست‌های یکپارچه‌سازی از storybook با حالت‌های مختلف Error Boundary استفاده کنید: عادی، خطا، حالت پس از بازنشانی. تست خودکار Boundary تضمین می‌کند که هنگام تغییر کامپوننت، fallback UI در production به درستی کار می‌کند. پوشش تست هر Boundary باید یک الزام اجباری code review برای پروژه‌های React Native باشد.

سوالات متداول

چرا Error Boundary با کامپوننت‌های تابعی کار نمی‌کند؟

React Error Boundary را فقط از طریق کامپوننت‌های کلاسی پیاده‌سازی می‌کند، زیرا دسترسی به متدهای چرخه حیات componentDidCatch و getDerivedStateFromError لازم است. کامپوننت‌های تابعی چنین متدهایی ندارند. کتابخانه react-error-boundary یک wrapper کلاسی آماده با API هوک برای سهولت استفاده ارائه می‌دهد.

Error Boundary چگونه بر عملکرد تأثیر می‌گذارد؟

تأثیر حداقلی است — Error Boundary در هر رندر درخت فرزند یک بررسی وضعیت اضافه می‌کند. مقایسه state.hasError یک عملیات O(1) با پیچیدگی ثابت است. در نبود خطاها overhead وجود ندارد. فقط هنگام وقوع خطا، Boundary یک رندر اضافی fallback UI انجام می‌دهد.

آیا لازم است هر کامپوننت در Error Boundary پیچیده شود؟

خیر، 2–3 سطح کافی است: ریشه Boundary برای کل برنامه، صفحه Boundary برای هر شاخه ناوبری و محلی Boundary برای ویجت‌های بحرانی (فرم پرداخت، نقشه، چت). تعداد بیش از حد Boundary معماری را بدون سود قابل توجه پیچیده می‌کند.

Error Boundary با Suspense در React 18+ چگونه کار می‌کند؟

Error Boundary و Suspense مستقل هستند: Suspense بارگذاری (Promise در حال انتظار در React 18+) را می‌گیرد، Error Boundary خطاهای رندر را می‌گیرد. می‌توان آنها را ترکیب کرد: <ErrorBoundary><Suspense><Component /></Suspense></ErrorBoundary>. Suspense در هنگام بارگذاری اول اجرا می‌شود، Error Boundary — در خطای کامپوننت بارگذاری‌شده.

تفاوت Error Boundary و try-catch در React چیست؟

try-catch خطاها را در کد امری همگام می‌گیرد، اما نمی‌تواند خطاهای رندر JSX را بگیرد. Error Boundary به طور خاص برای UI اعلامی طراحی شده است: خطاها را در render، lifecycle-hookها و سازنده‌های کامپوننت‌های فرزند می‌گیرد، که try-catch به دلیل ویژگی‌های رندر React نمی‌تواند انجام دهد.

خلاصه

  • Error Boundary — کامپوننت React برای گرفتن خطاهای رندر با نمایش fallback UI
  • ComponentDidCatch — متد ثبت خطاها، getDerivedStateFromError — برای مدیریت وضعیت UI
  • React Native برای جلوگیری از سقوط کامل برنامه به Error Boundary نیاز حیاتی دارد
  • محدودیت‌ها — خطاهای ناهمگام، خطاهای event-handler، SSR و لایه بومی را نمی‌گیرد
  • react-error-boundary — کتابخانه آماده با API هوک برای یکپارچه‌سازی آسان در پروژه
  • سطوح wrapper — ریشه، صفحه (توصیه‌شده) و محلی برای ویجت‌های بحرانی
  • Fallback UI باید معنادار باشد: پیام خطا، دکمه تلاش مجدد، تماس پشتیبانی

ما یک اپلیکیشن موبایل به صورت کلید در دست توسعه خواهیم داد

IT Sectr از سال 2017 برنامه‌های iOS و Android را برای استارتاپ‌ها و کسب‌وکارها ایجاد می‌کند. ما به شما مشاوره می‌دهیم و بهترین راه‌حل را پیشنهاد خواهیم کرد.

بحث درباره پروژه

همچنین بخوانید