Jak zrobić trwały portal w React

Mar 25 2023
Montowanie komponentów na różnych poziomach DOM jest niesamowite
Wszystkie nowoczesne frameworki front-end mają koncepcję komponentów, co pozwala nam oddzielić nasze obawy i lepiej rozwijać i utrzymywać projekty front-end. Ale zwykle komponenty nadrzędne i podrzędne również odwzorowują hierarchię elementów DOM.
Zdjęcie Glenna Carstensa-Petersa na Unsplash

Wszystkie nowoczesne frameworki front-end mają koncepcję komponentów, co pozwala nam oddzielić nasze obawy i lepiej rozwijać i utrzymywać projekty front-end. Ale zwykle komponenty nadrzędne i podrzędne również odwzorowują hierarchię elementów DOM. Co zrobić, jeśli musisz zamontować komponent w węzłach DOM?

W React możemy Portalto osiągnąć, co w niektórych przypadkach jest bardzo przydatne. Na przykład muszę określić pozycję, w której bieżący komponent potomny jest montowany na podstawie pewnego stanu. Zwykle są to okna dialogowe, wyświetlanie na pełnym ekranie itp.

Oto niestandardowy hak do implementacji tej funkcji:

Tutaj tworzę divjako węzeł operacyjny portalu i modyfikuję jego pozycję montowania, gdy zmiany container. Zauważ, że portalReffaktycznie można zoptymalizować za pomocą useImmutableRefValuewprowadzonych w moim ostatnim artykule:

Wygląda to więc tak:

import { createPortal } from 'react-dom';
import { useEffect, useCallback } from 'react';
import type { PropsWithChildren, RefObject, FC } from 'react';

import useImmutableRefValue from './useImmutableRefValue';

const usePersistPortal = (container?: HTMLElement | RefObject<HTMLElement>) => {
  const portal = useImmutableRefValue(() => document.createElement('div'));

  useEffect(() => {
    const root =
      container instanceof Element
        ? container
        : container?.current ?? document.body;

    root.appendChild(portal);
    return () => {
      root.removeChild(portal);
    };
  }, [container, portal]);

  const Portal: FC<PropsWithChildren<{}>> = useCallback(
    ({ children }) => createPortal(children, portal),
    [portal],
  );

  return {
    Portal,
  };
};

export default usePersistPortal;

Dzięki za przeczytanie, do zobaczenia w następnym, na zdrowie.

Nie jesteś członkiem Medium? Wesprzyj mnie tutaj, stając się jednym z nich .

Więcej treści na PlainEnglish.io .

Zapisz się do naszego bezpłatnego cotygodniowego biuletynu . Śledź nas na Twitterze , LinkedIn , YouTube i Discordzie .

Zainteresowany skalowaniem startupu oprogramowania ? Sprawdź obwód .