Table of Contents
Что такое Порталы? 🤔
Порталы позволяют рендерить дочерние элементы в DOM-узел, который находится вне DOM-иерархии родительского компонента.
ReactDOM.createPortal(child, container);
- child — это любой React-компонент, который может быть отрендерен, такой как элемент, строка или фрагмент. ( это то что будет вставлено)
- container — это DOM-элемент. (это куда будет втавлено)
Когда Использовать? ✍🏻
Порталы прекрастно подходят для таких задач как -
- модальные окна,
- подсказки,
- попапы,
- всплывающме элементы
Интересно
Через портал можно открыть новую вкладку браузера и отрисовать что либо из родителя и синхронизовать там данные с родителем
Пример Модального окна с использованием React.createPortal
1import React from "react";2import ReactDOM from "react-dom";34const Modal = ({ children, open }) => {5 if (open) {6 return ReactDOM.createPortal(7 <div className="modal">{children}</div>,8 document.body9 );10 }1112 return null;13};
Portal будет возвращен из render если переменная open true.
import Modal from './modal'const App = ({children})=> {const [open,setOpen] =React.useState(false)render() {return (<div><div><button onClick={() => setOpen(rue)}>open</button></div><Modal open={open}><div><h1>Hello from portal</h1><button onClick={() => setOpen(false)}>close</button></div></Modal></div>)}}
- Когда переменная open = false - наш DOM выглядит как обычно:
<html><head>....</head><body><div id="root" />...</body></html>
- Когда переменная open = true - в DOM добавляется наш елемент с модальным окном:
<html><head>....</head><body><div id="root" />...<div class="modal"><div><h1>Hello from portal</h1><button>close</button></div></div></body></html>
Важно
Tак как в качестве контейнера мы указали document.body наш новоиспеченный элемент добавился в body - потому что Portal монтируется в DOM как дочерний элемент ближайшего родительского узла. Это очень важный момент который нужно помнить, если вы делаете всплывающие окна или поздсказки то контейнером для них должен быть не document.body, а элемент на который они указывают.
Всплытие событий через порталы
Несмотря на то, что портал может быть где угодно в дереве DOM, он ведет себя как обычный дочерний элемент React во всех отношениях.
Такие функции, как контекст, работают как и ранее, независимо от того, является ли дочерний элемент порталом, поскольку портал все еще существует в дереве React независимо от его положения в дереве DOM. Это же касается и всплытия события.
Важно
Событие, созданное внутри портала, будет распространяться к предкам в объемлющем дереве React, даже если они не являются предками в дереве DOM.
Почитать 📚
Практика 👩💻👨💻
Создать компонент <Tooltip/>
const App = () => {return (<Tooltip content="Tooltip for hello"><p>Hello</p></Tooltip>);};
При вызове события
onMouseEnter
на дочерний элемент компонента Tooltip, должна показаться подсказка из property contentПри событии
onMouseEnter
подсказка должна быть скрытаКомпонент Tooltip должен использовать
ReactDOM.createPortal