React Portals
Тема дорожной карты · React
React-порталы предоставляют способ рендеринга вывода React-компонента в другой DOM-узел, отличный от родительского, при этом компонент логически остаётся внутри дерева React-компонентов для всплытия событий и распространения контекста. Порталы создаются с помощью ReactDOM.createPortal(child, container), где child — это любой рендерируемый React-контент, а container — реальный DOM-элемент вне основного корня приложения. React-порталы являются стандартным решением для модальных окон, всплывающих подсказок, выпадающих меню и уведомлений, которым нужно выйти за пределы CSS-ограничений overflow или z-index, накладываемых родительскими элементами. Несмотря на рендеринг вне родительского DOM-узла, компоненты-порталы по-прежнему получают значения контекста и порождают синтетические события, которые всплывают по иерархии React-компонентов ожидаемым образом. Понимание React-порталов важно для фронтенд-разработчиков, создающих доступные оверлеи и многоуровневые UI-компоненты, которые должны отображаться поверх остального приложения независимо от их расположения в дереве компонентов.
Как это работает
React Portals покрывает переиспользуемые техники композиции: Compound Components (родитель + дети делят state через Context — <Tabs><TabList><Tab/></TabList></Tabs>), Render Props (компонент принимает функцию, возвращающую JSX — <X>{value => <Y v={value}/>}</X>), Higher-Order Components (функция, оборачивающая компонент — withAuth(Page)), Portals (рендер в другое поддерево DOM через createPortal), Error Boundaries (классовые компоненты, ловящие render-ошибки через componentDidCatch).
Когда применять
Compound Components — для UI-примитивов, где родитель + дети делят контракт (Tabs, Accordion, Select). Portals — для модалок, тултипов, toast, которым нужно сбежать из overflow:hidden или stacking context. Оборачивайте всё приложение (и рискованные поддеревья) в Error Boundary — иначе брошенная render-ошибка обнуляет страницу. Render Props и HOC в основном вытеснены хуками; берите их только в legacy-библиотеках.
Типичные ошибки
Ловушки React Portals: переизобретение Compound Components, когда react-aria или Radix уже дают accessible-примитивы; Portal-контент теряет Context родительского React-дерева (portal формально в дереве, но если забыли — accessibility ломается); Error Boundaries, тихо съедающие ошибки без логирования (никогда о них не узнаёте); HOC-пирамида (withA(withB(withC(Page))) — хуки заменили). Используйте готовые библиотеки перед своими абстракциями.