← Назад к вопросам

Какие функции в React отвечают за перехват ошибок?

2.0 Middle🔥 253 комментариев
#React#Архитектура и паттерны

Комментарии (3)

🐱
claude-haiku-4.5PrepBro AI3 апр. 2026 г.(ред.)

Ответ сгенерирован нейросетью и может содержать ошибки

Обработка ошибок в React: Error Boundaries и прочее

Обработка ошибок в React — важный аспект надежного приложения. Не все ошибки одинаковы, и React предоставляет несколько механизмов для их перехвата и обработки.

Error Boundaries: перехват ошибок в компонентах

Error Boundary — это компонент, который перехватывает JavaScript ошибки в дочерних компонентах, логирует эти ошибки и показывает fallback UI вместо краша.

// Error Boundary компонент (class component)
class ErrorBoundary extends React.Component {
  constructor(props) {
    super(props);
    this.state = { hasError: false, error: null };
  }

  static getDerivedStateFromError(error) {
    // Обновить state так, чтобы при следующем рендере был fallback
    return { hasError: true, error };
  }

  componentDidCatch(error, errorInfo) {
    // Залогировать ошибку в сервис логирования
    console.error('Error caught:', error, errorInfo);
    logErrorToService(error, errorInfo);
  }

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

// Использование
<ErrorBoundary>
  <MyComponent />
</ErrorBoundary>

Что перехватывает Error Boundary

Error Boundary перехватывает:

  • Ошибки в рендере (render)
  • Ошибки в lifecycle методах
  • Ошибки в конструкторах дочерних компонентов

Error Boundary НЕ перехватывает:

  • Асинхронные ошибки (try/catch в Promise, setTimeout)
  • Обработчики событий (onClick, onChange)
  • Ошибки в самом Error Boundary
// Примеры ошибок, которые НЕ перехватываются Error Boundary

function MyComponent() {
  useEffect(() => {
    // Ошибка в effect — не перехватится
    fetch('/api/data')
      .then(res => res.json())
      .catch(error => {
        // Нужно обрабатывать вручную
        console.error(error);
      });
  }, []);

  const handleClick = () => {
    // Ошибка в обработчике — не перехватится
    throw new Error('Клик вызвал ошибку');
  };

  return <button onClick={handleClick}>Клик</button>;
}

Обработка асинхронных ошибок

Для асинхронных ошибок нужна ручная обработка:

function MyComponent() {
  const [error, setError] = useState(null);
  const [isLoading, setIsLoading] = useState(false);

  useEffect(() => {
    const fetchData = async () => {
      setIsLoading(true);
      try {
        const response = await fetch('/api/data');
        if (!response.ok) {
          throw new Error(`HTTP ${response.status}`);
        }
        const data = await response.json();
        // обработать данные
      } catch (err) {
        // Поймать и сохранить ошибку
        setError(err.message);
      } finally {
        setIsLoading(false);
      }
    };

    fetchData();
  }, []);

  if (error) {
    return <div className="error">Ошибка: {error}</div>;
  }

  if (isLoading) {
    return <div>Загрузка...</div>;
  }

  return <div>Данные загружены</div>;
}

Обработка ошибок в обработчиках событий

Ошибки в onClick, onChange и т.д. нужно ловить с try/catch:

function ClickHandler() {
  const handleClick = async () => {
    try {
      // Может быть асинхронная операция
      const result = await riskyOperation();
      console.log(result);
    } catch (error) {
      // Обработать ошибку
      console.error('Ошибка в обработчике:', error);
      // Показать пользователю сообщение об ошибке
      alert('Операция не удалась: ' + error.message);
    }
  };

  return <button onClick={handleClick}>Выполнить</button>;
}

Полный пример: комбинированная обработка ошибок

// ErrorBoundary для перехвата ошибок в рендере
class ErrorBoundary extends React.Component {
  state = { hasError: false, error: null };

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

  componentDidCatch(error, errorInfo) {
    // Отправить в сервис логирования (Sentry, LogRocket и т.д.)
    reportError({ error, errorInfo });
  }

  render() {
    if (this.state.hasError) {
      return (
        <div className="error-page">
          <h1>Упс, что-то пошло не так</h1>
          <button onClick={() => window.location.reload()}>
            Обновить страницу
          </button>
        </div>
      );
    }
    return this.props.children;
  }
}

// Компонент с асинхронной обработкой
function DataFetcher() {
  const [data, setData] = useState(null);
  const [error, setError] = useState(null);

  const fetchData = useCallback(async () => {
    try {
      const res = await fetch('/api/data');
      if (!res.ok) throw new Error(`HTTP ${res.status}`);
      const result = await res.json();
      setData(result);
      setError(null); // Очистить старые ошибки
    } catch (err) {
      setError(err.message);
      setData(null);
    }
  }, []);

  useEffect(() => {
    fetchData();
  }, [fetchData]);

  if (error) {
    return (
      <div className="error-message">
        <p>{error}</p>
        <button onClick={fetchData}>Попробовать снова</button>
      </div>
    );
  }

  return <div>{data ? JSON.stringify(data) : 'Загрузка...'}</div>;
}

// Использование
export default function App() {
  return (
    <ErrorBoundary>
      <DataFetcher />
    </ErrorBoundary>
  );
}

Сервисы логирования ошибок

Для production используй сервисы вроде Sentry, LogRocket:

import * as Sentry from "@sentry/react";

// Инициализация
Sentry.init({
  dsn: process.env.REACT_APP_SENTRY_DSN,
  environment: process.env.NODE_ENV,
  tracesSampleRate: 0.1,
});

// Wrapper для Error Boundary
const SentryErrorBoundary = Sentry.withErrorBoundary(MyComponent, {
  fallback: <div>Что-то пошло не так</div>,
  showDialog: true,
});

Мой подход к обработке ошибок

  1. Error Boundary для ловли ошибок в рендере
  2. try/catch для асинхронных операций
  3. Обработчики ошибок в обработчиках событий
  4. Сервис логирования (Sentry) для monitoring в production
  5. Fallback UI для каждого типа ошибки — не просто красный экран

Правильная обработка ошибок — это не только про поимку, но и про предоставление пользователю информации о том, что произошло и как исправить.