Dansk

En guide til React Portals, der dækker brug, implementering og fordele ved at gengive indhold uden for det normale komponenthierarki.

React Portals: Gengivelse af Indhold Uden for Komponenttræet

React portals giver en kraftfuld mekanisme til at gengive børnekomponenter i en DOM-node, der eksisterer uden for forælderkomponentens DOM-hierarki. Denne teknik er uvurderlig i forskellige scenarier, såsom modaler, tooltips og situationer, hvor du har brug for præcis kontrol over elementers positionering og stabling på siden.

Hvad er React Portals?

I en typisk React-applikation gengives komponenter inden for en streng hierarkisk struktur. Forælderkomponenten indeholder børnekomponenter, og så videre. Nogle gange er der dog brug for at bryde fri fra denne struktur. Det er her, React portals kommer ind i billedet. En portal giver dig mulighed for at gengive en komponents indhold i en anden del af DOM'en, selvom den del ikke er en direkte efterkommer af komponenten i React-træet.

Forestil dig, at du har en modal-komponent, der skal vises på det øverste niveau af din applikation, uanset hvor den gengives i komponenttræet. Uden portals kunne du forsøge at opnå dette ved hjælp af absolut positionering og z-index, hvilket kan føre til komplekse stylingproblemer og potentielle konflikter. Med portals kan du direkte gengive modalens indhold i en specifik DOM-node, såsom et dedikeret "modal-root"-element, og dermed sikre, at det altid gengives på det korrekte niveau.

Hvorfor bruge React Portals?

React Portals løser flere almindelige udfordringer inden for webudvikling:

Sådan implementerer du React Portals

At bruge React Portals er ligetil. Her er en trin-for-trin guide:

  1. Opret en DOM-node: Først skal du oprette en DOM-node, hvor du vil gengive portalens indhold. Dette gøres typisk i din `index.html`-fil. For eksempel:
    <div id="modal-root"></div>
  2. Brug `ReactDOM.createPortal()`: I din React-komponent skal du bruge `ReactDOM.createPortal()`-metoden til at gengive indholdet i den oprettede DOM-node. Denne metode tager to argumenter: React-noden (det indhold, du vil gengive) og DOM-noden, hvor du vil gengive det.
    import ReactDOM from 'react-dom';
    
    function MyComponent() {
      return ReactDOM.createPortal(
        <div>Dette indhold gengives i modal-root!</div>,
        document.getElementById('modal-root')
      );
    }
    
    export default MyComponent;
  3. Gengiv komponenten: Gengiv komponenten, der indeholder portalen, som du ville gøre med enhver anden React-komponent.
    function App() {
      return (
        <div>
          <h1>My App</h1>
          <MyComponent />
        </div>
      );
    }
    
    export default App;

I dette eksempel vil indholdet i `MyComponent` blive gengivet inde i `modal-root`-elementet, selvom `MyComponent` gengives inde i `App`-komponenten.

Eksempel: Oprettelse af en Modal-komponent med React Portals

Lad os oprette en komplet modal-komponent ved hjælp af React Portals. Dette eksempel inkluderer grundlæggende styling og funktionalitet til at åbne og lukke modalen.

import React, { useState } from 'react';
import ReactDOM from 'react-dom';

const modalRoot = document.getElementById('modal-root');

function Modal({ children, onClose }) {
  const [isOpen, setIsOpen] = useState(true);

  const handleClose = () => {
    setIsOpen(false);
    onClose();
  };

  if (!isOpen) return null;

  return ReactDOM.createPortal(
    <div className="modal-overlay">
      <div className="modal">
        <div className="modal-content">
          {children}
        </div>
        <button onClick={handleClose}>Luk</button>
      </div>
    </div>,
    modalRoot
  );
}

function App() {
  const [showModal, setShowModal] = useState(false);

  const handleOpenModal = () => {
    setShowModal(true);
  };

  const handleCloseModal = () => {
    setShowModal(false);
  };

  return (
    <div>
      <h1>My App</h1>
      <button onClick={handleOpenModal}>Åbn Modal</button>
      {showModal && (
        <Modal onClose={handleCloseModal}>
          <h2>Modalindhold</h2>
          <p>Dette er indholdet i modalen.</p>
        </Modal>
      )}
    </div>
  );
}

export default App;

I dette eksempel:

Du skal også tilføje noget CSS-styling til `modal-overlay`- og `modal`-klasserne for at placere modalen korrekt på skærmen. For eksempel:

.modal-overlay {
  position: fixed;
  top: 0;
  left: 0;
  width: 100%;
  height: 100%;
  background-color: rgba(0, 0, 0, 0.5);
  display: flex;
  justify-content: center;
  align-items: center;
  z-index: 1000;
}

.modal {
  background-color: white;
  padding: 20px;
  border-radius: 5px;
}

.modal-content {
  margin-bottom: 10px;
}

Håndtering af Events med Portals

En vigtig overvejelse ved brug af portals er, hvordan events håndteres. Event bubbling fungerer anderledes med portals end med standard React-komponenter.

Når en event opstår inden i en portal, vil den boble op gennem DOM-træet som normalt. Reacts event-system behandler dog portalen som en almindelig React-node, hvilket betyder, at events også vil boble op gennem det React-komponenttræ, der indeholder portalen.

Dette kan nogle gange føre til uventet adfærd, hvis man ikke er forsigtig. For eksempel, hvis du har en event handler på en forælderkomponent, der kun skal udløses af events inden for den komponent, kan den også blive udløst af events inden for portalen.

For at undgå disse problemer kan du bruge `stopPropagation()`-metoden på event-objektet for at forhindre, at eventen bobler længere op. Alternativt kan du bruge Reacts syntetiske events og betinget gengivelse til at kontrollere, hvornår event handlers udløses.

Her er et eksempel på brug af `stopPropagation()` for at forhindre en event i at boble op til forælderkomponenten:

function MyComponent() {
  const handleClick = (event) => {
    event.stopPropagation();
    console.log('Klikket inde i portalen!');
  };

  return ReactDOM.createPortal(
    <div onClick={handleClick}>Dette indhold gengives i portalen.</div>,
    document.getElementById('portal-root')
  );
}

I dette eksempel vil et klik på indholdet i portalen udløse `handleClick`-funktionen, men eventen vil ikke boble op til nogen forælderkomponenter.

Bedste Praksis for Brug af React Portals

Her er nogle bedste praksisser, du skal huske på, når du arbejder med React Portals:

Alternativer til React Portals

Selvom React Portals er et kraftfuldt værktøj, findes der alternative tilgange, du kan bruge for at opnå lignende resultater. Nogle almindelige alternativer inkluderer:

Valget af tilgang afhænger af de specifikke krav til din applikation og kompleksiteten af de UI-elementer, du forsøger at oprette. Portals er generelt den bedste mulighed, når du har brug for præcis kontrol over elementers positionering og stabling og ønsker at undgå CSS-konflikter.

Globale Overvejelser

Når man udvikler applikationer til et globalt publikum, er det vigtigt at overveje faktorer som lokalisering, tilgængelighed og kulturelle forskelle. React Portals kan spille en rolle i at håndtere disse overvejelser:

Ved at tage disse globale overvejelser i betragtning kan du skabe mere inkluderende og brugervenlige applikationer for et mangfoldigt publikum.

Konklusion

React Portals er et kraftfuldt og alsidigt værktøj til at gengive indhold uden for det standard komponenttræ. De giver en ren og elegant løsning på almindelige UI-mønstre som modaler, tooltips og popovers. Ved at forstå, hvordan portals fungerer, og ved at følge bedste praksis, kan du skabe mere fleksible, vedligeholdelsesvenlige og tilgængelige React-applikationer.

Eksperimenter med portals i dine egne projekter og opdag de mange måder, de kan forenkle din UI-udviklingsworkflow. Husk at overveje eventhåndtering, tilgængelighed og globale hensyn, når du bruger portals i produktionsapplikationer.

Ved at mestre React Portals kan du tage dine React-færdigheder til det næste niveau og bygge mere sofistikerede og brugervenlige webapplikationer for et globalt publikum.