Skip to main content

Помилка в компоненті

Коротко: будь-яка необроблена помилка під час рендеру/коміту компонента "рве" все React-піддерево від найближчого Error Boundary до кореня. Якщо межі немає, падає весь кореневий React-вузол → білий екран.


Що саме відбувається

  • Під час render-фази React викликає твої компоненти (функції/конструктори), будує віртуальне дерево. Якщо всередині відбувається throw (або помилка на кшталт cannot read property of undefined), React перериває реконсиляцію.
  • Далі йде commit-фаза (застосування змін до DOM). Помилка в ефектах layout (useLayoutEffect) або в lifecycle у класів також може призвести до аварійного розмонтування піддерева.
  • Якщо поруч немає Error Boundary, React не знає, як безпечно продовжити → розмонтовує все дерево застосунку (або відповідний суб-root). Звідси "впав компонент - зник весь екран".

Error Boundary - запобіжник

Error Boundary перехоплює помилки в дочірніх компонентах під час:

  • render
  • конструкторів класових компонентів
  • методів життєвого циклу і показує fallback UI замість падіння всього застосунку.

Мінімальний приклад

javascript
class ErrorBoundary extends React.Component< { fallback?: React.ReactNode }, { hasError: boolean } > { constructor(props) { super(props); this.state = { hasError: false }; } static getDerivedStateFromError() { return { hasError: true }; } componentDidCatch(error: any, info: any) { // логуємо в Sentry/GlitchTip тощо } render() { return this.state.hasError ? (this.props.fallback ?? <h1>Щось пішло не так</h1>) : this.props.children; } }

Обгортаємо ризикові зони:

javascript
<ErrorBoundary fallback={<Oops />}> <RiskyWidget /> </ErrorBoundary>

Для функцій зручно взяти готовий пакет react-error-boundary.


Що не ловить Error Boundary

  • Помилки в обробниках подій (там використовуй try/catch).
  • Помилки в асинхронному коді (таймери, fetch, проміси, await) - лови вручну (try/catch, .catch, window.onunhandledrejection).
  • Помилки на сервері при SSR.
  • Помилки в самому Error Boundary (очевидно).

Типові причини "падінь"

  • Доступ до undefined/null при рендері (немає перевірок даних).
  • Нескінченні рендер-цикли (зміна стейту в render/беззалежному useEffect).
  • Непередбачувані ефекти в useLayoutEffect/useEffect, що кидають виняток.
  • Гідрація (SSR) з критичним неспівпадінням розмітки.
  • Кидання винятків як частина логіки (наприклад, у поєднанні з Suspense) без коректного boundary.

Практика, щоб застосунок не "падав цілком"

  1. Сегментуй застосунок кількома Error Boundaries: шапка, сайдбар, контент, модалки - щоб падіння віджета не валило все.
  2. Фолбеки "розумні": "Спробувати знову", "Повідомити про помилку", телеметрія.
  3. Захищай рендер: перевірки даних (if (!data) return <Skeleton/>), опціональні ланцюжки, типи (TypeScript).
  4. Асинхронність: try/catch навколо await, централізований .catch, обробники onerror/unhandledrejection.
  5. Моніторинг: підключи Sentry/GlitchTip - ловити стеки, частоти, користувачів.
  6. Feature flags/kill-switches: швидко вимикати проблемні фічі.
  7. Тести і Strict Mode: dev-режим React викликає деякі шляхи двічі - допомагає виявити помилки раніше.

Підсумок

Помилка в компоненті "ламає все", тому що без найближчого Error Boundary React змушений розмонтувати все дерево до кореня для збереження цілісності UI. Рішення - локалізувати ризики за допомогою Error Boundaries, акуратної асинхронної обробки та захисних перевірок на етапі рендеру.

Коротка відповідь

Для співбесіди
Premium

Коротка відповідь допоможе вам впевнено відповідати на цю тему під час співбесіди.