Encodera

Спасибо, что читаете!

Пожертвуйте сайту, мы стараемся ради вас.

Оглавление

Границы ошибок

Если компонент бросит исключение во время отрисовки, React уберёт со страницы всё приложение — пользователь увидит пустой экран. Граница ошибок (error boundary) — компонент-обёртка, который ловит такие ошибки в своих детях и показывает вместо них запасной интерфейс. Остальная часть страницы продолжает работать.

Что ломает страницу

Пусть в блоге статья пришла без заголовка, а компонент на это не рассчитан:

// src/components/PostCard.jsx
export default function PostCard({ post }) {
  return <h2>{post.title.toUpperCase()}</h2>;
}

Если post.title равен undefined, вызов toUpperCase() бросит TypeError. Без границы ошибок вся страница станет белой, а ошибка появится только в консоли.

Компонент-граница

Границу ошибок можно написать только классом — для неё нет хука. Создайте src/components/ErrorBoundary.jsx один раз и используйте во всём проекте:

// src/components/ErrorBoundary.jsx
import { Component } from 'react';
 
export default class ErrorBoundary extends Component {
  state = { hasError: false };
 
  static getDerivedStateFromError() {
    return { hasError: true };
  }
 
  componentDidCatch(error, info) {
    console.error('Ошибка в компоненте:', error, info.componentStack);
  }
 
  render() {
    if (this.state.hasError) {
      return this.props.fallback;
    }
    return this.props.children;
  }
}

getDerivedStateFromError вызывается при ошибке в любом потомке и переключает состояние. componentDidCatch — место, чтобы записать ошибку в журнал или отправить в сервис мониторинга. Пока ошибки нет, граница просто выводит children.

Использование

Оберните опасную часть страницы и передайте запасную разметку в проп fallback:

// src/pages/HomePage.jsx
import ErrorBoundary from '../components/ErrorBoundary.jsx';
import PostList from '../components/PostList.jsx';
 
export default function HomePage() {
  return (
    <>
      <h1>Блог</h1>
      <ErrorBoundary fallback={<p>Не удалось показать статьи.</p>}>
        <PostList />
      </ErrorBoundary>
    </>
  );
}

Если в PostList или любой карточке внутри случится ошибка, вместо списка появится «Не удалось показать статьи.», а заголовок «Блог» и меню останутся на месте.

Где ставить границы

МестоЧто защищает
Вокруг всего AppХотя бы сообщение вместо белого экрана
Вокруг каждой страницы в макетеОшибка на странице не ломает меню
Вокруг независимого блокаКомментарии упали, статья осталась

Готовая библиотека

Чтобы не писать класс, можно установить пакет react-error-boundary (npm install react-error-boundary). Его компонент ErrorBoundary принимает тот же проп fallback и умеет сбрасывать ошибку кнопкой «Попробовать снова».

Частая ошибка

Граница ловит только ошибки во время отрисовки и в эффектах. Ошибки в обработчиках событий и в асинхронном коде она не видит:

// Граница НЕ поймает эту ошибку: она в обработчике клика.
<button onClick={() => { throw new Error('Сбой'); }}>Удалить</button>

Такие ошибки обрабатывайте сами через try/catch и показывайте сообщение через состояние, как в уроке про загрузку данных.

Спасибо, что читаете!

Пожертвуйте сайту, мы стараемся ради вас.