Come creare un portale persistente in React

Mar 25 2023
I componenti di montaggio tra i livelli DOM sono fantastici
I moderni framework front-end hanno tutti il ​​concetto di componenti, che ci consente di separare le nostre preoccupazioni e sviluppare e mantenere meglio i progetti front-end. Ma di solito, anche i componenti padre e figlio mappano la gerarchia degli elementi DOM.
Foto di Glenn Carstens-Peters su Unsplash

I moderni framework front-end hanno tutti il ​​concetto di componenti, che ci consente di separare le nostre preoccupazioni e sviluppare e mantenere meglio i progetti front-end. Ma di solito, anche i componenti padre e figlio mappano la gerarchia degli elementi DOM. Cosa succede se è necessario montare un componente tra i nodi DOM?

In React, possiamo usare Portalper raggiungere questo obiettivo, il che è molto utile in alcuni casi. Ad esempio, devo determinare la posizione in cui è montato il componente figlio corrente in base a uno stato. Di solito ci sono finestre di dialogo, visualizzazione a schermo intero, ecc.

Ecco un hook personalizzato per implementare questa funzione:

Qui creo un divcome nodo operativo del portale e modifico la sua posizione di montaggio quando containercambia. Nota che portalRefpuò effettivamente essere ottimizzato usando useImmutableRefValueintrodotto nel mio ultimo articolo:

Quindi sembra così:

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;

Grazie per aver letto, ci vediamo nel prossimo, evviva.

Non sei un membro medio? Supportami qui diventando uno .

Altri contenuti su PlainEnglish.io .

Iscriviti alla nostra newsletter settimanale gratuita . Seguici su Twitter , LinkedIn , YouTube e Discord .

Ti interessa scalare l'avvio del tuo software ? Scopri Circuito .