
Портал (Portal) - это механизм в React, который позволяет рендерить компоненты внутри других элементов, которые находятся вне иерархии DOM-дерева компонента-родителя. Это означает, что порталы позволяют размещать компоненты в произвольных местах страницы, включая области, которые обычно находятся за пределами корневого элемента React-приложения.
Порталы особенно полезны в случаях, когда нам нужно отобразить компоненты поверх других элементов, например, при создании модальных окон, всплывающих подсказок, или приложений, которые должны отображаться внутри веб-страниц другого сайта.
В React, порталы создаются с помощью компонента ReactDOM.createPortal(child, container), где child - это дочерний компонент, который необходимо отобразить, а container - это DOM-элемент, в который нужно поместить этот компонент.
Например, для создания портала, который будет отображать компонент Modal в элементе modal-root, который находится вне корневого элемента React-приложения, можно использовать следующий код:
import React from "react"
import ReactDOM from "react-dom"
function Modal(props) {
return ReactDOM.createPortal(props.children, document.getElementById("modal-root"))
}
export default ModalВ этом примере компонент Modal создает портал, который отображает его дочерние компоненты в элементе с идентификатором modal-root. Этот элемент может быть создан где угодно на странице, и компонент Modal будет отображаться внутри него, независимо от того, где находится корневой элемент React-приложения.
**Portal и z-index
Portals предоставляют способ решения проблемы с z-index для элементов, которые должны быть размещены вне иерархии компонентов.
Когда элементы рендерятся внутри компонента в React, они обычно наследуют свойства стилей и z-index от своих родительских компонентов. Это может вызвать проблемы, когда вам нужно разместить элемент поверх других элементов на странице.
С помощью порталов вы можете рендерить компонент в DOM-узле, который находится вне иерархии компонентов. Это позволяет вам контролировать положение элемента независимо от иерархии компонентов и перекрывать другие элементы с помощью стилей.
Вот пример использования порталов в React:
import React from "react"
import ReactDOM from "react-dom"
const Modal = ({ children }) => {
return ReactDOM.createPortal(
<div className="modal">{children}</div>,
document.getElementById("modal-root"), // DOM-узел, в который будет рендериться портал
)
}
const App = () => {
return (
<div>
<h1>My App</h1>
<Modal>
<p>This is a modal</p>
</Modal>
</div>
)
}
ReactDOM.render(<App />, document.getElementById("root"))В приведенном примере мы создаем компонент Modal, который рендерит дочерние элементы в портале с помощью createPortal(). Мы указываем document.getElementById('modal-root') вторым аргументом createPortal(), чтобы портал был рендерен внутри элемента с id “modal-root”, который мы предварительно создали в DOM.