ReactJS - Portалы: Врата в новые dimensionы ваших React приложений
Здравствуйте,野心勃勃ые разработчики React! Сегодня мы отправимся в увлекательное путешествие в мир React Portals. Представьте, что вы строите дом (ваше React приложение), и вдруг понимаете, что вам needed的秘密ный passage, чтобы transportить что-то из одной комнаты в другую, не passes через главный коридор. Именно то, что делают React Portals для ваших компонентов!
Что такое React Portals?
React Portals предоставляют первый класс способов рендеринга descendents в DOM узел, который существует вне DOM иерархии родительского компонента. На более простом языке, это как создание червоточины, которая позволяет вам рендерить компонент в другом месте DOM дерева, даже если он по-прежнему часть вашей React компонентной иерархии.
Зачем нам нужны Portals?
Вы можете задаться вопросом: "Почему я не могу просто рендерить мой компонент wherever хочу?" Ну, в большинстве случаев, вы можете! Но есть сценарии, где Portals могут быть полезны:
- Модальные对话框и
- Подсказки
- Плавающие меню
- Вidgets, которые нужно вывести за пределы их контейнера
Давайте погрузимся глубже в то, как работают Portals и как их использовать.
Создание вашего первого Portala
Чтобы создать Portal, мы используем метод ReactDOM.createPortal()
. Вот базовый пример:
import React from 'react';
import ReactDOM from 'react-dom';
function MyPortalComponent() {
return ReactDOM.createPortal(
<h1>Я рендерюсь в другом месте!</h1>,
document.getElementById('portal-root')
);
}
В этом примере мы создаем Portal, который рендерит <h1>
элемент в DOM узле с идентификатором 'portal-root'. Этот узел должен существовать где-то в вашем HTML, вне корневого элемента вашей main React приложения.
Давайте разберем метод ReactDOM.createPortal()
:
- Первый аргумент - это React элемент, который вы хотите рендерить.
- Второй аргумент - это DOM элемент, где вы хотите его рендерить.
Реальный пример: Модальный диалог
Давайте создадим более практичный пример - модальный对话框, который appears поверх содержимого вашего приложения.
import React, { useState } from 'react';
import ReactDOM from 'react-dom';
function Modal({ isOpen, onClose, children }) {
if (!isOpen) return null;
return ReactDOM.createPortal(
<div className="modal-overlay">
<div className="modal-content">
{children}
<button onClick={onClose}>Закрыть</button>
</div>
</div>,
document.getElementById('modal-root')
);
}
function App() {
const [isModalOpen, setIsModalOpen] = useState(false);
return (
<div>
<h1>Добро пожаловать в мое приложение</h1>
<button onClick={() => setIsModalOpen(true)}>Открыть модальный диалог</button>
<Modal isOpen={isModalOpen} onClose={() => setIsModalOpen(false)}>
<h2>Это модальный диалог</h2>
<p>Он рендерится خارج главного React дерева!</p>
</Modal>
</div>
);
}
В этом примере мы создали перерабатываемый Modal
компонент, который использует Portal для рендеринга своего содержимого. Компонент App
контролирует видимость модального диалога с помощью хука React useState
.
Давайте разберем, что происходит:
- Компонент
Modal
проверяет, должен ли он быть open (isOpen
проп). - Если открыт, он создает Portal, который рендерит свое содержимое в элемент 'modal-root'.
- Содержимое модального диалога включает кнопку закрытия, которая активирует
onClose
проп. - В компоненте
App
мы используем состояние для управления видимостью модального диалога.
Пропagation событий через Portals
Один из fascininating аспектов Portals заключается в том, что несмотря на то, что они могут рендерить содержимое в anywhere в DOM дереве, событя продолжают пузыриться вверх через React дерево, как expected. Давайте посмотрим пример:
import React, { useState } from 'react';
import ReactDOM from 'react-dom';
function Parent() {
const [clicks, setClicks] = useState(0);
const handleClick = () => {
setClicks(clicks + 1);
};
return (
<div onClick={handleClick}>
<h1>Кликов: {clicks}</h1>
<Portal>
<Child />
</Portal>
</div>
);
}
function Portal({ children }) {
return ReactDOM.createPortal(
children,
document.getElementById('portal-root')
);
}
function Child() {
return <button>Нажми меня!</button>;
}
В этом примере, нажатие на кнопку внутри Portala все равно активирует обработчик кликов в родительском компоненте, увеличивая счетчик кликов. Это поведение incredibly полезно, так как оно поддерживает ожидаемое распространение событий, несмотря на то, где компонент действительно рендерится в DOM.
Лучшие практики и соображения
Используя Portals, имейте в виду следующие моменты:
- Доступность: Убедитесь, что содержимое вашего Portala доступно, особенно для экранных readers.
- Обработка событий: Помните, событья пузырятся через React дерево, а не DOM дерево.
- Оформление: Содержимое Portala может require отдельных соображений по оформлению.
- Очистка: Не забудьте очистить ваши Portals, когда компонент отмонтируется.
Методы Portals
Вот таблица ключевых методов, связанных с React Portals:
Метод | Описание |
---|---|
ReactDOM.createPortal(child, container) |
Создает portal. child - любой рендеримый React child, а container - DOM элемент. |
ReactDOM.unmountComponentAtNode(container) |
Удаляет смонтированный React компонент из DOM и очищает его обработчики собыний и состояние. |
Заключение
React Portals - это мощная функция, которая позволяет вам вырваться из традиционной иерархии компонентов при рендеринге. Они особенно полезны для создания модальных диалогов, подсказок и других UI элементов, которые должны визуально "вырываться" из своих контейнеров.
помните, с великой силой приходит великая ответственность! Используйте Portals мудро и всегда учитывайте влияние на структуру и доступность вашего приложения.
Счастливого кодирования, и пусть ваши Portals всегда ведут в захватывающие новые dimensionы ваших React приложений!
Credits: Image by storyset