Error Boundary — що це таке, компонент React Native і обробка помилок

Автор: IT Sectr Опубліковано: 2026-05-27 Час читання: 8 хв

Error Boundary — це компонент React, який перехоплює JavaScript-помилки в своєму дочірньому дереві компонентів і відображає запасний інтерфейс замість сторінки аварійного завершення. У контексті React Native він запобігає повному збою застосунку при нефатальних помилках рендерингу. Згідно з React Documentation, 2024, error boundary ловить помилки в методах render, хуках життєвого циклу та конструкторах дочірніх компонентів, дозволяючи застосунку продовжити роботу. У React Native це особливо критично, оскільки мобільний застосунок не перезавантажується через F5 — користувач втрачає сеанс цілком.

Головне

  • Error Boundary — React-компонент для перехоплення помилок рендерингу в дочірньому дереві
  • ComponentDidCatch — метод життєвого циклу, який отримує помилку та інформацію про стек
  • Fallback UI — запасний інтерфейс, що відображається замість зламаного компонента
  • React Native використовує Error Boundary для запобігання повному збою застосунку
  • Обмеження — Error Boundary не ловить помилки в асинхронному коді та обробниках подій

Що таке Error Boundary

Error Boundary — це механізм React для поступової деградації при помилках рендерингу. Введений у React 16 (2017) як компонент-обгортка, що реалізує один із двох методів життєвого циклу: static getDerivedStateFromError або componentDidCatch. Error Boundary дозволяє показувати користувачеві осмислене повідомлення замість пустого білого екрана або повного збою застосунку.

Як з’явився Error Boundary

До React 16 будь-яка необроблена помилка в render призводила до повного збою застосунку з демонтажем усього DOM-дерева. У веб-застосунках це означало пустий білий екран, у React Native — повний збій із поверненням на головний екран. Команда React ввела Error Boundary як аналог catch-блоку для декларативного UI, запозичивши концепцію з підходу “let it crash” у мові Erlang.

Значення для React Native

У React Native відсутність Error Boundary означає повний збій застосунку при будь-якій помилці рендерингу. Користувач втрачає весь поточний сеанс без можливості відновлення. Error Boundary у React Native критично важливий, оскільки мобільні застосунки не перезавантажуються як веб-сторінки — сеанс користувача безповоротно втрачається, і користувачеві доводиться починати все заново.

Як працює Error Boundary у React Native

Error Boundary працює на рівні React-дерева. Коли дочірній компонент викидає помилку в render або життєвому циклі, React не демонтує все дерево, а передає керування найближчому Error Boundary вище в ієрархії. Boundary викликає getDerivedStateFromError, встановлює state.hasError = true і рендерить запасний інтерфейс замість зламаної гілки компонентів.

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("Caught by boundary:", error)
        Crashlytics.recordException(error)
    }

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

getDerivedStateFromError встановлює стан для рендерингу запасного інтерфейсу — це статичний метод, що викликається на етапі рендерингу до фіксації змін. componentDidCatch виконується на етапі фіксації та призначений для побічних ефектів: логування, надсилання звітів про збій до 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>
)

Рівні обгортки — Error Boundary можна розміщувати на різних рівнях ієрархії. Один глобальний Boundary на корені застосунку покаже запасний інтерфейс при будь-якій помилці, але навігація все одно збережеться. Кілька Boundary на рівні екранів дозволяють ізолювати помилки: якщо один екран зламався, інші продовжують працювати незалежно. react-error-boundary спрощує механізм скидання через хук useErrorBoundary, дозволяючи скинути стан без перезавантаження. Для типових проектів схема з трьома рівнями Boundary вважається оптимальною для React Native застосунків.

Скидання стану Error Boundary

Після виникнення помилки користувач може натиснути кнопку “Повторити”, яка скидає hasError у false і перерендерює дочірнє дерево. Механізм скидання важливий для відновлення працездатності застосунку без перезавантаження. У react-error-boundary використовується onReset callback, який може очищати кеш, перезапитувати дані або оновлювати стан вище по дереву.

Обмеження Error Boundary

Error Boundary не ловить асинхронні помилки — помилки в setTimeout, setInterval, Promise, async/await. React не може перехопити помилки поза циклом рендерингу та хуками життєвого циклу, оскільки вони виконуються в інших контекстах виконання. Для асинхронних помилок потрібен окремий try-catch в обробниках або глобальний обробник події unhandledrejection.

Обробники подій

Помилки в onClick, onChange та інших обробниках подій не перехоплюються Error Boundary, оскільки вони виконуються поза React-рендерингом. Обробка помилок для обробників подій має бути всередині самого обробника через try-catch. Бібліотека react-error-boundary надає хук useErrorHandler для пробросу помилок з обробників подій у найближчий Boundary.

Серверний рендеринг і Next.js

Error Boundary не працює на серверній стороні в Next.js або Gatsby. Методи getDerivedStateFromError і componentDidCatch не викликаються при SSR, оскільки методи життєвого циклу доступні тільки в браузері. Для серверних помилок потрібна окрема стратегія: try-catch у getServerSideProps, запасні сторінки 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 відповідає за свій фрагмент інтерфейсу та не впливає на сусідні компоненти при виникненні помилки.

Логування та моніторинг

Завжди передавайте помилку в Crashlytics або Sentry через componentDidCatch. Додавайте контекст: назву екрана, userId, версію застосунку, параметри навігації. У Sentry доступні breadcrumbs — послідовність дій користувача до помилки. Для аналізу частоти non-fatal помилок використовуйте дашборди Crashlytics із групуванням по issue.

Запасний інтерфейс

Не використовуйте “голий” запасний інтерфейс — робіть осмислений інтерфейс. Рекомендований набір для React Native: повідомлення про помилку (user-friendly, не технічне), кнопка “Повторити”, посилання на підтримку або чат. Уникайте пустого View — користувач подумає, що застосунок зламався повністю, і закриє його. Запасний інтерфейс має бути вбудований у загальний дизайн застосунку.

Тестування Error Boundary

Тестуйте кожен Error Boundary за допомогою React Testing Library або React Native Testing Library. Створіть компонент-тригер, який викидає помилку при рендерингу, і перевірте, що відображається запасний інтерфейс. Для інтеграційних тестів використовуйте storybook з різними станами Error Boundary: нормальний, помилковий, стан після скидання. Автоматизоване тестування Boundary гарантує, що при зміні компонента запасний інтерфейс продовжує коректно працювати в production. Покриття тестами кожного Boundary має бути обов’язковою вимогою code review для React Native проектів.

Часті запитання

Чому Error Boundary не працює з функціональними компонентами?

React реалізує Error Boundary тільки через класові компоненти, оскільки потрібен доступ до методів життєвого циклу componentDidCatch і getDerivedStateFromError. Функціональні компоненти не мають таких методів. Бібліотека react-error-boundary надає готову класову обгортку з хуковим API для зручності використання.

Як Error Boundary впливає на продуктивність?

Вплив мінімальний — Error Boundary додає перевірку стану при кожному рендері дочірнього дерева. Порівняння state.hasError — це O(1) операція з константною складністю. При відсутності помилок навантаження відсутнє. Тільки при виникненні помилки Boundary виконує додатковий рендер запасного інтерфейсу.

Чи потрібно обгортати кожен компонент у Error Boundary?

Ні, достатньо 2–3 рівнів: кореневий Boundary для всього застосунку, екранний Boundary для кожної навігаційної гілки та локальний Boundary для критичних віджетів (платіжна форма, карта, чат). Надмірна кількість Boundary ускладнює архітектуру без значної користі.

Як Error Boundary працює з Suspense у React 18+?

Error Boundary і Suspense незалежні: Suspense ловить завантаження (pending 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, хуках життєвого циклу та конструкторах дочірніх компонентів, що try-catch зробити не може через особливості React-рендерингу.

Підсумки

  • Error Boundary — React-компонент для перехоплення помилок рендерингу з відображенням запасного інтерфейсу
  • ComponentDidCatch — метод для логування помилок, getDerivedStateFromError — для керування станом UI
  • React Native критично потребує Error Boundary для запобігання повному збою застосунку
  • Обмеження — не ловить асинхронні помилки, помилки в обробниках подій, SSR та нативний шар
  • react-error-boundary — готова бібліотека з хуковим API для зручної інтеграції в проект
  • Рівні обгортки — кореневий, екранний (рекомендується) і локальний для критичних віджетів
  • Запасний інтерфейс має бути осмисленим: повідомлення про помилку, кнопка повтору, контакт підтримки

Ми розробимо мобільний застосунок під ключ

IT Sectr створює застосунки для iOS та Android для стартапів і бізнесу з 2017 року. Ми проконсультуємо вас і запропонуємо найкраще рішення.

Обговорити проект

Читайте також