Фрагменты позволяют группировать несколько элементов без добавления лишних узлов в DOM. В Preact это особенно важно, поскольку каждый лишний узел увеличивает нагрузку на виртуальный DOM и усложняет структуру компонента.
Использование фрагментов реализуется с помощью компонента
Fragment:
import { h, Fragment } from 'preact';
function List() {
return (
<Fragment>
<li>Элемент 1</li>
<li>Элемент 2</li>
<li>Элемент 3</li>
</Fragment>
);
}
Ключевые особенности:
function ItemList({ items }) {
return (
<Fragment>
{items.map(item => (
<li key={item.id}>{item.name}</li>
))}
</Fragment>
);
}
Фрагменты также поддерживаются в короткой записи с пустыми тегами
<>...</>:
function Example() {
return (
<>
<h1>Заголовок</h1>
<p>Описание</p>
</>
);
}
Такой синтаксис делает код компактным, особенно при возвращении
нескольких элементов без необходимости импортировать
Fragment.
Порталы позволяют рендерить элементы вне обычной иерархии DOM-компонента, что особенно важно для модальных окон, всплывающих подсказок и других UI-элементов, которые должны существовать на верхнем уровне документа.
В Preact для создания портала используется функция
createPortal из пакета preact/compat:
import { h } from 'preact';
import { createPortal } from 'preact/compat';
function Modal({ children }) {
const modalRoot = document.getElementById('modal-root');
return createPortal(
<div className="modal">
{children}
</div>,
modalRoot
);
}
Особенности порталов:
Модальное окно с порталами и фрагментами:
function App() {
const [isOpen, setIsOpen] = useState(false);
return (
<>
<button onCl ick={() => setIsOpen(true)}>Открыть модал</button>
{isOpen && (
<Modal>
<Fragment>
<h2>Заголовок модала</h2>
<p>Содержимое модала</p>
<button onCl ick={() => setIsOpen(false)}>Закрыть</button>
</Fragment>
</Modal>
)}
</>
);
}
В данном примере:
div.Порталы сохраняют доступ к контексту родительских компонентов:
import { createContext } from 'preact';
const ThemeContext = createContext('light');
function ThemedModal() {
const theme = useContext(ThemeContext);
return createPortal(
<div className={`modal ${theme}`}>Контент с темой {theme}</div>,
document.getElementById('modal-root')
);
}
Таким образом, можно использовать порталы без потери контекста, что обеспечивает гибкость при создании сложных интерфейсов.
key даже внутри фрагментов.Фрагменты и порталы в Preact позволяют строить чистую и оптимизированную архитектуру компонентов, сохраняя при этом гибкость в управлении DOM и контекстом.