109 lines
5.1 KiB
Markdown
109 lines
5.1 KiB
Markdown
---
|
||
sidebar_position: 9
|
||
---
|
||
|
||
# Render portal
|
||
Источник: DeepSeek
|
||
|
||
В контексте библиотеки **React**, **Portal (портал)** — это механизм, который позволяет рендерить дочерние элементы
|
||
|
||
Использование порталов (**Portals**) в React позволяет рендерить элементы вне основного DOM-дерева, сохраняя при этом их
|
||
логическую связь с React-компонентами. Это особенно полезно для модальных окон, всплывающих подсказок, уведомлений и
|
||
других элементов, которые должны отображаться поверх основного интерфейса.
|
||
|
||
## Как использовать порталы в React
|
||
|
||
1. **Создайте целевой DOM-элемент:** \
|
||
В вашем HTML-файле создайте элемент, в который будет рендериться содержимое портала. Обычно это делается в
|
||
`public/index.html` (если вы используете Create React App).
|
||
|
||
```html
|
||
|
||
<div id="root"></div>
|
||
<div id="modal-root"></div> <!-- Сюда будет рендериться модальное окно -->
|
||
```
|
||
|
||
2. **Используйте ReactDOM.createPortal:**
|
||
В React-компоненте используйте метод `ReactDOM.createPortal`, чтобы рендерить содержимое в целевой DOM-элемент.
|
||
3. **Пример использования портала:**
|
||
|
||
```jsx
|
||
import React from 'react';
|
||
import ReactDOM from 'react-dom';
|
||
|
||
// Компонент модального окна
|
||
function Modal({children, onClose}) {
|
||
return ReactDOM.createPortal(
|
||
<div style={{
|
||
position: 'fixed',
|
||
top: '0',
|
||
left: '0',
|
||
width: '100%',
|
||
height: '100%',
|
||
backgroundColor: 'rgba(0, 0, 0, 0.5)',
|
||
display: 'flex',
|
||
justifyContent: 'center',
|
||
alignItems: 'center',
|
||
}}>
|
||
<div style={{
|
||
backgroundColor: 'white',
|
||
padding: '20px',
|
||
borderRadius: '10px',
|
||
boxShadow: '0 2px 10px rgba(0, 0, 0, 0.1)',
|
||
}}>
|
||
{children}
|
||
<button onClick={onClose} style={{marginTop: '10px'}}>Закрыть</button>
|
||
</div>
|
||
</div>,
|
||
document.getElementById('modal-root') // Целевой DOM-элемент
|
||
);
|
||
}
|
||
|
||
// Основной компонент
|
||
function App() {
|
||
const [isModalOpen, setIsModalOpen] = React.useState(false);
|
||
|
||
return (
|
||
<div>
|
||
<h1>Пример использования портала</h1>
|
||
<button onClick={() => setIsModalOpen(true)}>Открыть модальное окно</button>
|
||
|
||
{isModalOpen && (
|
||
<Modal onClose={() => setIsModalOpen(false)}>
|
||
<p>Это модальное окно, отрендеренное через портал!</p>
|
||
</Modal>
|
||
)}
|
||
</div>
|
||
);
|
||
}
|
||
|
||
export default App;
|
||
```
|
||
|
||
## Объяснение кода:
|
||
|
||
1. **Целевой DOM-элемент:**
|
||
- В `public/index.html` создан элемент с `id="modal-root"`, в который будет рендериться модальное окно.
|
||
2. **Компонент `Modal`:**
|
||
- Использует `ReactDOM.createPortal`, чтобы рендерить содержимое модального окна в modal-root.
|
||
- Первый аргумент `createPortal` — это JSX, который нужно отрендерить.
|
||
- Второй аргумент — это DOM-элемент, в который будет вставлено содержимое.
|
||
3. **Компонент `App`:**
|
||
- Управляет состоянием модального окна (`isModalOpen`).
|
||
- При нажатии на кнопку "Открыть модальное окно" состояние изменяется, и модальное окно отображается через портал.
|
||
|
||
## Преимущества использования порталов:
|
||
1. Логическая связь:
|
||
- Элементы, рендерящиеся через портал, остаются частью React-дерева. Это означает, что они могут получать пропсы,
|
||
контекст и участвовать в жизненном цикле компонентов.
|
||
2. Визуальное отделение:
|
||
- Позволяет отображать элементы вне основного DOM-дерева, что полезно для модальных окон, всплывающих подсказок и
|
||
т.д.
|
||
3. Упрощение стилей:
|
||
- Позволяет избежать проблем с z-index и наложением элементов.
|
||
|
||
## Когда использовать порталы?
|
||
- Модальные окна.
|
||
- Всплывающие подсказки (tooltips).
|
||
- Уведомления.
|
||
- Любые элементы, которые должны отображаться поверх основного интерфейса. |