webroad.online
  1. 1Веб
  2. 2HTML
  3. 3CSS
  4. 4JavaScript
  5. 5TypeScript
  6. 6Git
  7. 7Инструменты
  8. 8React
  9. 9Стейт-менеджмент
  10. 10Next.js
  11. 11Формы
  12. 12Данные и бэкенд
  13. 13SEO
  14. 14Tailwind CSS
  15. 15Анимации
  16. 16Тестирование
  17. 17Архитектура
React · Урок 5 из 7

Context, порталы, error boundaries

Без prop drilling, рендер в другом месте DOM, ошибки изолированы по секциям.

Обновлено

Что такое Context, порталы и error boundaries

Три инструмента React для ситуаций, которые обычные props и состояние решают плохо:

Инструмент Какую проблему решает
Context значение нужно многим компонентам глубоко в дереве, без props на каждом уровне
Портал элемент нужно отрисовать в другом месте DOM (модалку, тултип), а не там, где он в дереве
Error boundary ошибка в одном компоненте не должна ломать всю страницу

Context

Проблема — prop drilling: user проходит через 5 компонентов, которые его не используют, только чтобы дойти до шестого.

const ThemeContext = createContext<'light' | 'dark'>('light')   // значение по умолчанию

export function ThemeProvider({ children }: { children: React.ReactNode }) {
  const [theme, setTheme] = useState<'light' | 'dark'>('light')
  return <ThemeContext value={theme}>{children}</ThemeContext>   // React 19: прямо <Context>
}

function Badge() {
  const theme = use(ThemeContext)                                // или useContext(ThemeContext)
}
Правило Подробности
побеждает ближайший провайдер сверху можно переопределить значение для секции
нет провайдера → значение по умолчанию из createContext
изменение значения перерисовывает всех потребителей кладите в Context редко меняющиеся значения
новый объект на каждом рендере = лишние перерисовки useMemo на значение или разделите на несколько контекстов
в Next провайдер — Client Component кладёте в layout.tsx, оборачивая children (они остаются Server Components)

Для глобального часто меняющегося состояния → Zustand / Redux.

Порталы

Модалка, отрисованная внутри карточки с overflow: hidden или в контексте наложения, обрезается или оказывается под другими элементами. createPortal рендерит её в другой узел DOM (обычно в конец body), но в дереве React она остаётся там, где вы её написали — получает Context, а события всплывают к React-родителям.

import { createPortal } from 'react-dom'

function Modal({ children }: { children: React.ReactNode }) {
  return createPortal(<div className="fixed inset-0 grid place-items-center bg-black/40">{children}</div>, document.body)
}

Современная альтернатива без портала: нативный элемент <dialog> с showModal() и Popover API (меню «Все темы» в этом приложении) — оба рендерятся в top layer, поверх всего, а фокусом и Esc управляет браузер.

Error boundaries

Ошибка, брошенная при рендере компонента, по умолчанию размонтирует всё приложение. Error boundary ловит ошибку и показывает запасной интерфейс только для этой секции.

Где Как
Next.js App Router файл error.tsx в сегменте — см. Layout, состояния и навигация
обычный React класс с getDerivedStateFromError или библиотека react-error-boundary

Не ловят: ошибки в обработчиках событий (их ловят через try/catch), в асинхронном коде вне рендера, в Server Actions (их возвращают как состояние).

Коротко

  • Context = передача без prop drilling; побеждает ближайший провайдер; только для редко меняющихся значений.
  • Портал = рендер в другом месте DOM при сохранении места в дереве React; <dialog> и popover — нативные альтернативы.
  • Error boundary = ошибка ломает только свою секцию; в Next — error.tsx.

Официальные источники

Упражнения

Была ли страница полезной?

Один клик — без регистрации.