Portals

Atomico — это библиотека для создания компонентов и интерфейсов, основанная на реактивности и поддерживающая декларативный стиль программирования. Важной концепцией, которая стоит за Atomico, является использование порталов (Portals), позволяющих управлять рендерингом компонентов в различных частях DOM-дерева, даже если эти части не находятся внутри родительского компонента.

Что такое портал?

Портал в Atomico — это механизм, позволяющий “выводить” элементы из обычного потока DOM в другую часть документа. Например, можно рендерить модальные окна, всплывающие подсказки, уведомления и другие компоненты, которые не должны следовать иерархии родительского компонента, но при этом должны оставаться частью его логики. Таким образом, портал предоставляет разработчику возможность разместить компонент в произвольном месте документа, не влияя на остальную структуру интерфейса.

Как работает портал?

В традиционных библиотеках компоненты рендерятся внутри родительских компонентов и следуют их иерархии. Это может ограничивать возможности для динамических элементов, таких как модальные окна. Atomico решает эту проблему, позволяя использовать порталы для рендеринга компонентов в другом месте DOM, что облегчает создание динамических интерфейсов.

Atomico предоставляет простую обертку для создания порталов, используя механизм, похожий на стандартный React Portal. Портал в Atomico позволяет компоненты отображаться не только внутри их родителя, но и в любой точке DOM-дерева. Это удобно для таких элементов, как модальные окна, всплывающие окна, уведомления и других UI-элементов, которые должны быть независимы от текущей иерархии компонентов.

Создание портала в Atomico

Для использования портала в Atomico необходимо воспользоваться хуком usePortal(), который позволяет привязать компонент к указанному DOM-узлу, отличному от родительского. Портал будет рендерить элемент именно там, куда его укажет разработчик, сохраняя при этом реактивность и все связанные с этим преимущества.

Пример базового использования портала:

import { html, useState, useEffect, usePortal } from "atomico";

function Modal({ open, onClose }) {
  return open
    ? html`
        <div class="modal">
          <div class="content">
            <button @click=${onClose}>Закрыть</button>
            <p>Это модальное окно!</p>
          </div>
        </div>
      `
    : null;
}

export function App() {
  const [isOpen, setIsOpen] = useState(false);
  const portal = usePortal(); // Создание порта для рендеринга в другом месте

  return html`
    <div>
      <button @click=${() => setIsOpen(true)}>Открыть модальное окно</button>
      ${portal(html`<${Modal} open=${isOpen} onCl ose=${() => setIsOpen(false)} />`)}
    </div>
  `;
}

В этом примере компонент Modal рендерится в DOM через портал, и его содержимое отображается в том месте, где будет вызван usePortal(). Важно, что портал работает только в том случае, если он подключен к компоненту в рамках того же дерева. В случае с модальными окнами это позволяет помещать их в body или любой другой контейнер, независимо от того, где находится компонент.

Особенности порталов в Atomico

  • Реактивность: Портал в Atomico сохраняет реактивность, что означает, что любые изменения состояния внутри компонента, подключенного через портал, будут автоматически отслеживаться и обновляться.
  • Гибкость: Портал может быть использован для рендеринга компонентов в любые части DOM, например, в body или в другие контейнеры, независимо от иерархии компонентов.
  • Простота использования: Использование порталов в Atomico максимально упрощено благодаря встроенному хуку usePortal(), который минимизирует необходимость в дополнительном коде для настройки и управления порталом.

Применение порталов

  1. Модальные окна: Порталы идеально подходят для отображения модальных окон, так как они позволяют вставлять окно в верхнюю часть DOM, не нарушая структуру страницы.

  2. Всплывающие подсказки и уведомления: Когда нужно отобразить временный элемент (например, всплывающее уведомление), портал помогает избежать изменения основной структуры страницы.

  3. Контекстные меню: Для создания контекстных меню, которые должны быть расположены в произвольной части экрана, также используются порталы.

  4. Тулбары и панели инструментов: Панели, расположенные в верхней части страницы или в другом контейнере, можно легко рендерить через портал, не нарушая основную структуру пользовательского интерфейса.

Учет производительности при использовании порталов

Хотя порталы могут значительно улучшить архитектуру приложения, их использование требует внимательности при оптимизации производительности. Каждый раз, когда портал активируется, его содержимое рендерится в другом месте DOM. Это может привести к увеличению числа рендеров, если не использовать оптимизации, такие как мемоизация компонентов или управление состоянием.

Для улучшения производительности можно использовать методы атомарного обновления, избегая ненужных перерисовок, что позволяет добиться быстродействия при большом числе компонентов, использующих портал.

Заключение

Порталы в Atomico обеспечивают гибкость и удобство в создании динамических компонентов, таких как модальные окна, уведомления, всплывающие подсказки и другие элементы интерфейса. Благодаря встроенной поддержке реактивности и простоте использования порталов можно без труда управлять рендерингом элементов вне родительской иерархии. Это позволяет значительно улучшить пользовательский опыт и упростить разработку сложных интерфейсов.