Запропонувати правкуПокращити цю статтюДопрацюйте відповідь до «Помилка в компоненті». Ваші зміни проходять модерацію перед публікацією.Потрібне підтвердженняКонтентЩо ви змінюєте🇺🇸EN🇺🇦UAПереглядЗаголовок (UA)Коротка відповідь (UA)Будь-яка необроблена помилка під час рендеру/коміту компонента **рве все React-піддерево від найближчого Error Boundary до кореня**. **Ключове:** якщо межі немає, падає весь кореневий React-вузол - білий екран, тож рішення - локалізувати ризики за допомогою Error Boundaries.Показується над повною відповіддю для швидкого нагадування.Відповідь (UA)ЗображенняКоротко: **будь-яка необроблена помилка під час рендеру/коміту компонента "рве" все 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, акуратної асинхронної обробки та захисних перевірок на етапі рендеру.Для рев’юераПримітка для модератора (необов’язково)Бачить лише модератор. Прискорює рев’ю.