Cómo hacer un portal persistente en React

Mar 25 2023
El montaje de componentes a través de los niveles DOM es increíble
Todos los marcos front-end modernos tienen el concepto de componentes, lo que nos permite separar nuestras preocupaciones y desarrollar y mantener mejor los proyectos front-end. Pero, por lo general, los componentes principal y secundario también mapean la jerarquía de los elementos DOM.
Foto de Glenn Carstens-Peters en Unsplash

Todos los marcos front-end modernos tienen el concepto de componentes, lo que nos permite separar nuestras preocupaciones y desarrollar y mantener mejor los proyectos front-end. Pero, por lo general, los componentes principal y secundario también mapean la jerarquía de los elementos DOM. ¿Qué sucede si necesita montar un componente en los nodos DOM?

En React, podemos usar Portalpara lograr esto, lo cual es muy útil en algunos casos. Por ejemplo, necesito determinar la posición en la que se monta el componente secundario actual en función de algún estado. Comúnmente hay cuadros de diálogo, pantalla completa, etc.

Aquí hay un gancho personalizado para implementar esta función:

Aquí creo un divnodo de operación del Portal y modifico su posición de montaje cuando cambia container. Tenga en cuenta que portalRefen realidad se puede optimizar usando useImmutableRefValuelo introducido en mi último artículo:

Entonces se ve así:

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;

Gracias por leer, te veo en el próximo, saludos.

¿No eres miembro de Medium? Apóyame aquí convirtiéndote en uno .

Más contenido en PlainEnglish.io .

Regístrese para recibir nuestro boletín semanal gratuito . Síganos en Twitter , LinkedIn , YouTube y Discord .

¿ Interesado en escalar su inicio de software ? Visita Circuito .