Como fazer um portal persistente em React

Mar 25 2023
A montagem de componentes nos níveis de DOM é incrível
Todos os frameworks front-end modernos possuem o conceito de componentes, o que nos permite separar nossas preocupações e desenvolver e manter melhor os projetos front-end. Mas geralmente, os componentes pai e filho também mapeiam a hierarquia dos elementos DOM.
Foto de Glenn Carstens-Peters no Unsplash

Todos os frameworks front-end modernos possuem o conceito de componentes, o que nos permite separar nossas preocupações e desenvolver e manter melhor os projetos front-end. Mas geralmente, os componentes pai e filho também mapeiam a hierarquia dos elementos DOM. E se você precisar montar um componente em nós DOM?

No React, podemos usar Portalpara conseguir isso, o que é muito útil em alguns casos. Por exemplo, preciso determinar a posição em que o componente filho atual está montado com base em algum estado. Normalmente, existem caixas de diálogo, exibição em tela cheia, etc.

Aqui está um gancho personalizado para implementar esse recurso:

Aqui eu crio um divcomo o nodo de operação do Portal, e modifico sua posição de montagem quando o mesmo containermuda. Observe que portalRefpode realmente ser otimizado usando useImmutableRefValueo apresentado em meu último artigo:

Então fica assim:

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;

Obrigado por ler, te vejo no próximo, abraços.

Não é um membro Médio? Apoie-me aqui, tornando-se um .

Mais conteúdo em PlainEnglish.io .

Assine nosso boletim informativo semanal gratuito . Siga-nos no Twitter , LinkedIn , YouTube e Discord .

Interessado em dimensionar sua inicialização de software ? Conheça o Circuito .