Error boundaries

Урок про error boundaries: как перехватить ошибку рендера в части дерева и показать запасной UI вместо «белого экрана».

Error boundary — компонент, который ловит ошибки JavaScript в дереве своих детей во время рендера, в методах жизненного цикла и в конструкторах, и рисует запасной UI вместо рухнувшего поддерева.

Проблема

Если компонент бросает исключение во время рендера, React по умолчанию размонтирует всё дерево — пользователь видит пустой экран. Это правильно с точки зрения целостности (лучше ничего, чем сломанный UI), но плохо для UX. Error boundary локализует катастрофу: падает только обёрнутая часть, остальное приложение живёт.

Как написать

На сегодня error boundary можно создать только классовым компонентом — хуки этого не умеют. Нужны два метода: getDerivedStateFromError (переключить состояние в «ошибку») и componentDidCatch (залогировать).

class ErrorBoundary extends React.Component {
  state = { hasError: false };

  static getDerivedStateFromError(error) {
    // вызывается на фазе render — возвращаем новое состояние
    return { hasError: true };
  }

  componentDidCatch(error, info) {
    // вызывается на фазе commit — место для логирования
    console.error("Поймана ошибка:", error, info.componentStack);
  }

  render() {
    if (this.state.hasError) {
      return <p>Что-то пошло не так. Перезагрузите страницу.</p>;
    }
    return this.props.children;
  }
}

Использование — оборачиваем рискованное поддерево:

<ErrorBoundary>
  <Dashboard />
</ErrorBoundary>

Что error boundary НЕ ловит

Это частый источник путаницы. Boundary перехватывает ошибки рендера, но не ловит:

  • ошибки в обработчиках событий (onClick и т.п.) — там используйте обычный try/catch;
  • ошибки в асинхронном коде (setTimeout, промисы, fetch) — тоже try/catch/.catch();
  • ошибки в самом error boundary;
  • ошибки на сервере при SSR (там своя обработка).

Куда ставить границы

УровеньЗачем
корень приложенияпоследний рубеж: показать «извините, ошибка» вместо белого экрана
вокруг крупных независимых зон (виджет, дашборд, чат)падение одной зоны не роняет остальные
вокруг сторонних/рискованных компонентовизолировать ненадёжный код

На практике пишут один ErrorBoundary и переиспользуют его, часто с пропом fallback. В реальных проектах берут готовый react-error-boundary — он добавляет хук сброса и удобный API, но под капотом это тот же классовый компонент.

Итог

  • Error boundary показывает запасной UI вместо упавшего поддерева.
  • Реализуется классом: getDerivedStateFromError + componentDidCatch.
  • Не ловит ошибки обработчиков и асинхронного кода — там try/catch.
  • Ставьте границы в корне и вокруг крупных независимых зон.
Проверьте себя
1. Что делает error boundary?
AЛовит все возможные ошибки приложения
BПоказывает запасной UI вместо упавшего во время рендера поддерева
CПерезапускает сервер
DЛогирует сетевые запросы
2. Какие ошибки error boundary НЕ ловит?
AОшибки в конструкторе дочернего компонента
BОшибки в обработчиках событий и в асинхронном коде
CОшибки в методах жизненного цикла
DОшибки рендера детей
3. С помощью чего реализуется error boundary?
AХука useError
BКлассового компонента с getDerivedStateFromError и componentDidCatch
CФункции createBoundary
DАтрибута onError на div
Поддержать проект