Что такое error boundary в React?

MiddleReact · Frontend·Обновлено 11 июля 2026
Коротко
Error boundary — это React-компонент, который перехватывает JavaScript-ошибки в дереве дочерних компонентов, логирует их и отображает запасной UI вместо упавшего дерева.

Error Boundary в React

Error boundary (граница ошибки) — специальный класс-компонент, который реализует один или оба метода жизненного цикла: static getDerivedStateFromError() и componentDidCatch(). Благодаря им компонент перехватывает необработанные ошибки, возникающие при рендере, в методах жизненного цикла и в конструкторах дочерних компонентов.

Как это работает

Когда дочерний компонент выбрасывает исключение во время рендера, React ищет ближайший error boundary вверх по дереву компонентов. Если он найден — вызывается getDerivedStateFromError, который обновляет состояние, и на следующем рендере отображается fallback-UI. Метод componentDidCatch вызывается уже после рендера и предназначен для логирования ошибки.

Что error boundary не перехватывает

  • Ошибки в обработчиках событий (используйте обычный try/catch)
  • Асинхронный код (setTimeout, fetch, промисы)
  • Ошибки серверного рендеринга (SSR)
  • Ошибки внутри самого error boundary

Функциональные компоненты

Error boundary нельзя написать как функциональный компонент — для этого обязательно нужен класс. Однако существуют библиотеки, например react-error-boundary, которые предоставляют хук useErrorBoundary и компонент <ErrorBoundary> с удобным API.

Стратегия размещения

Error boundary можно оборачивать как всё приложение целиком (грубая защита), так и отдельные виджеты или маршруты — тогда падение одной части страницы не уронит остальные.

Пример

См. раздел с примерами кода ниже.

Восстановление после ошибки

Через componentDidCatch можно отправить ошибку в систему мониторинга (Sentry, Datadog). Кнопка «Попробовать снова» реализуется сбросом состояния error boundary — например методом resetErrorBoundary из react-error-boundary.

Что хочет услышать интервьюер

Понимание того, что error boundary — это именно класс-компонент, и объяснение почему (хуки не покрывают методы getDerivedStateFromError/componentDidCatch)

Знание двух ключевых методов жизненного цикла и разницы между ними: getDerivedStateFromError для рендера fallback-UI, componentDidCatch для логирования

Чёткое перечисление сценариев, которые error boundary НЕ перехватывает (обработчики событий, async-код)

Понимание стратегии размещения границ ошибок в дереве компонентов

Упоминание react-error-boundary как современного практичного решения

Пример: Классический error boundary

import React, { Component, ErrorInfo, ReactNode } from 'react';

interface Props {
  fallback: ReactNode;
  children: ReactNode;
}

interface State {
  hasError: boolean;
  error: Error | null;
}

class ErrorBoundary extends Component<Props, State> {
  state: State = { hasError: false, error: null };

  // Вызывается во время рендера — обновляем state, чтобы показать fallback
  static getDerivedStateFromError(error: Error): State {
    return { hasError: true, error };
  }

  // Вызывается после рендера — подходит для логирования
  componentDidCatch(error: Error, info: ErrorInfo): void {
    console.error('ErrorBoundary поймал ошибку:', error, info.componentStack);
    // sendToSentry(error, info);
  }

  render() {
    if (this.state.hasError) {
      return this.props.fallback;
    }
    return this.props.children;
  }
}

// Использование
function App() {
  return (
    <ErrorBoundary fallback={<p>Что-то пошло не так. Попробуйте обновить страницу.</p>}>
      <UserProfile />
    </ErrorBoundary>
  );
}

Пример: Современный подход с react-error-boundary

import { ErrorBoundary, useErrorBoundary } from 'react-error-boundary';

function FallbackComponent({ error, resetErrorBoundary }: {
  error: Error;
  resetErrorBoundary: () => void;
}) {
  return (
    <div role="alert">
      <p>Произошла ошибка: {error.message}</p>
      <button onClick={resetErrorBoundary}>Попробовать снова</button>
    </div>
  );
}

// Внутри дочернего компонента можно вручную сообщить об ошибке
function DataLoader() {
  const { showBoundary } = useErrorBoundary();

  async function fetchData() {
    try {
      const data = await api.getData();
      return data;
    } catch (err) {
      // Пробрасываем async-ошибку в ближайший error boundary
      showBoundary(err);
    }
  }

  return <button onClick={fetchData}>Загрузить</button>;
}

function App() {
  return (
    <ErrorBoundary
      FallbackComponent={FallbackComponent}
      onError={(error, info) => console.error(error, info)}
    >
      <DataLoader />
    </ErrorBoundary>
  );
}

Типичные ошибки

Попытка написать error boundary как функциональный компонент — это невозможно без сторонней обёртки

Уверенность, что error boundary поймает ошибку в onClick или других обработчиках событий

Путаница между getDerivedStateFromError (статический, для рендера) и componentDidCatch (для side-effects/логирования)

Один глобальный error boundary на всё приложение вместо точечной расстановки по критичным блокам

Забывают о том, что error boundary не ловит асинхронные ошибки (промисы, async/await)

Лучшие курсы по теме

изображение курса

TypeScript с нуля

Антон Ларичев
AI-тренажерыAI-тренажеры
Практика в студииПрактика в студии
Гарантия
Бонусы
иконка звёздочки рейтинга4.8
3 999 ₽ 6 990 ₽
Подробнее
изображение курса

Feature-Sliced Design

Антон Ларичев
AI-тренажерыAI-тренажеры
Практика в студииПрактика в студии
Гарантия
Бонусы
иконка звёздочки рейтинга4.5
3 999 ₽ 6 990 ₽
Подробнее
изображение курса

Next.js - с нуля

Антон Ларичев
AI-тренажерыAI-тренажеры
Практика в студииПрактика в студии
Гарантия
Бонусы
иконка звёздочки рейтинга4.7
3 999 ₽ 6 990 ₽
Подробнее