Обработка ошибок (Error Boundary)
React Error Boundary — class-компонент, перехватывающий ошибки рендеринга в дочерних компонентах и показывающий fallback вместо белого экрана.
Задача
Ошибка в одном React-компоненте не должна крашить всё приложение. Нужен «предохранитель», который поймает ошибку, залогирует её и покажет пользователю понятное сообщение.
Решение
// components/ErrorBoundary.tsx
import React, { Component, ErrorInfo, ReactNode } from 'react';
interface Props {
children: ReactNode;
fallback?: ReactNode;
onError?: (error: Error, info: ErrorInfo) => void;
}
interface State {
hasError: boolean;
error: Error | null;
}
class ErrorBoundary extends Component<Props, State> {
state: State = { hasError: false, error: null };
static getDerivedStateFromError(error: Error): State {
return { hasError: true, error };
}
componentDidCatch(error: Error, info: ErrorInfo) {
console.error('ErrorBoundary caught:', error, info.componentStack);
this.props.onError?.(error, info);
}
handleReset = () => {
this.setState({ hasError: false, error: null });
};
render {
if (this.state.hasError) {
return (
this.props.fallback ?? (
<div className="error-fallback">
<h2>Что-то пошло не так</h2>
<p>{this.state.error?.message}</p>
<button onClick={this.handleReset}>Попробовать снова</button>
</div>
)
);
}
return this.props.children;
}
}
export default ErrorBoundary;
Использование:
import ErrorBoundary from '@/components/ErrorBoundary';
// Обернуть всё приложение
function App() {
return (
<ErrorBoundary onError={(err) => logToSentry(err)}>
<Router />
</ErrorBoundary>
);
}
// Обернуть конкретную секцию с кастомным fallback
function Dashboard() {
return (
<div>
<ErrorBoundary fallback={<p>Виджет недоступен</p>}>
<ChartWidget />
</ErrorBoundary>
<ErrorBoundary>
<TableWidget />
</ErrorBoundary>
</div>
);
}
.error-fallback {
padding: 24px;
background: #fef2f2;
border: 1px solid #fecaca;
border-radius: 8px;
text-align: center;
}
.error-fallback h2 { color: #dc2626; margin-bottom: 8px; }
.error-fallback button { margin-top: 12px; padding: 8px 16px; }
Ключевые моменты
- Error Boundary работает только как class-компонент — функциональные компоненты не могут быть Error Boundary (на 2026 год).
getDerivedStateFromError— перехватывает ошибку и обновляет state для рендера fallback.componentDidCatch— для логирования (Sentry, DataDog и т.д.); не обновляет state.- Error Boundary не ловит: ошибки в обработчиках событий, асинхронные ошибки (
fetch), серверные ошибки — только ошибки при рендеринге.
Варианты
react-error-boundary— пакет с хукомuseErrorBoundaryи функциональным API для сброса.- Для асинхронных ошибок (fetch) — отдельно обрабатывай в
try/catchв хуке и прокидывай состояние.