Portaler for modaler og verktøytips
Bruk ReactDOM.createPortal til å gjengi underkomponenter i en annen DOM-node, slik at modaler og verktøytips kan unnslippe containere med overflow:hidden.
Portaler for modaler og verktøytips er en gratis leksjon i Frontend Academy på CoddyKit. Dette er leksjon 3 av 4. Du kan lese hele leksjonen gratis nedenfor – og deretter øve praktisk i nettleseren med en innebygd kodeeditor og en AI-veileder som er tilgjengelig døgnet rundt. Den er en del av læringsløpet i Frontend Academy, og fremdriften din synkroniseres mellom nettet og CoddyKit-appen. Kurset i Frontend Academy inneholder totalt 4 leksjoner.
Problemet med å unnslippe containere
Modaler og tooltips må gjengis øverst i DOM-en for å unnslippe overflow:hidden, z-index-stabling og transform-baserte kontekster i forelderen. Løsningen er portaler.
createPortal-API-et
createPortal(children, container) gjengir children i container (en hvilken som helst DOM-node), samtidig som de logisk sett forblir barn av React-komponenten når det gjelder hendelser og context.
import { createPortal } from 'react-dom';
function Modal({ children, onClose }) {
return createPortal(
<div className="modal-backdrop" onClick={onClose}>
<div className="modal-content" onClick={e => e.stopPropagation()}>
{children}
</div>
</div>,
document.body
);
}Portalcontainere
Vanlige mål er document.body, en dedikert #modal-root-div i index.html eller en container opprettet ved behov med en ref.
<!-- index.html -->
<div id="root"></div>
<div id="modal-root"></div>
// component:
const modalRoot = document.getElementById('modal-root');
return createPortal(<div>...</div>, modalRoot);Hvorfor ikke bare gjengi direkte?
Hvis en forelder har overflow: hidden, blir en modal i et barn beskåret. Hvis en forelder har transform: scale, blir modalens faste posisjonering relativ til forelderen. Portaler unngår alt dette.
Hendelser bobler fortsatt opp
Selv om innholdet gjengis et annet sted i DOM-en, bobler React-hendelser gjennom komponenttreet, ikke DOM-treet. Et klikk i portalen bobler fortsatt opp til onClick-behandlere i overordnede React-komponenter.
Lukk ved klikk på overlegg
Stopp hendelsespropageringen på modalinnholdet, slik at klikk inne i modalen ikke lukker den.
function Modal({ onClose, children }) {
return createPortal(
<div className="backdrop" onClick={onClose}>
<div className="content" onClick={e => e.stopPropagation()}>
{children}
</div>
</div>,
document.body
);
}Lukk med Escape-tasten
Legg til en keydown-lytter mens modalen er åpen, og fjern den når komponenten avmonteres.
useEffect(() => {
const onKey = (e) => { if (e.key === 'Escape') onClose(); };
window.addEventListener('keydown', onKey);
return () => window.removeEventListener('keydown', onKey);
}, [onClose]);Fokushåndtering i portaler
Når en modal åpnes: flytt fokuset inn i den, fang fokuset til modalen lukkes, og gjenopprett deretter fokuset til elementet som åpnet modalen. Bruk et bibliotek som focus-trap-react for å unngå å implementere dette på nytt.
Det native dialog-elementet
HTMLs <dialog> håndterer modalposisjonering, bakgrunn, fokusfanging og lukking med Escape innebygd. For de fleste modaler er dette et bedre utgangspunkt enn en portal.
function Modal({ open, onClose, children }) {
const ref = useRef(null);
useEffect(() => {
if (open) ref.current?.showModal();
else ref.current?.close();
}, [open]);
return (
<dialog ref={ref} onClose={onClose}>
{children}
</dialog>
);
}Tooltips og popovers
Tooltips posisjoneres relativt til et ankerelement. Portaler lar dem unnslippe stablingskontekster. Kombiner med floating-ui for kollisjonsdeteksjon, vending og posisjonering.
import { useFloating, autoUpdate } from '@floating-ui/react';
function Tooltip({ children, content }) {
const { refs, floatingStyles } = useFloating({ whileElementsMounted: autoUpdate });
const [open, setOpen] = useState(false);
return (
<>
<button ref={refs.setReference} onMouseEnter={() => setOpen(true)} onMouseLeave={() => setOpen(false)}>
{children}
</button>
{open && createPortal(
<div ref={refs.setFloating} style={floatingStyles}>{content}</div>,
document.body
)}
</>
);
}Forbehold ved SSR
document finnes ikke på serveren. Gjengi derfor enten bare på klienten (sjekk typeof window), eller bruk Next.js dynamic med ssr:false.
Tilgjengelighet: aria-modal
Modalcontainere bør ha role="dialog", aria-modal="true" og aria-labelledby som peker på modalens overskrift. Eller bruk native <dialog>.
Hurtigsjekk
Hvorfor bruke createPortal for modaler i stedet for å gjengi dem direkte i komponenttreet?
Oppsummering: Portaler
createPortal(children, container) gjengir DOM-en et annet sted, samtidig som det logiske React-treet beholdes. Det løser problemer med å unnslippe overflow, transform og z-index. Hendelser bobler fortsatt gjennom React-treet. Legg til lukking med Escape og fokushåndtering. Native <dialog> håndterer mye av dette for modaler. Kombiner med floating-ui for tooltips. Ikke glem SSR (sjekk typeof window).
Lær deg HTML med en AI-veileder – gratis
Skriv og kjør ekte kode i nettleseren, få umiddelbar hjelp fra en AI-veileder som er tilgjengelig døgnet rundt, og fortsett der du slapp – på nettet eller i appen.
- Kurs
- 41
- Leksjoner
- 163
Ofte stilte spørsmål
Er leksjonen «Portaler for modaler og verktøytips» gratis?
Ja – hele teksten i «Portaler for modaler og verktøytips» er gratis å lese her på nettet. For å øve interaktivt med en innebygd kodeeditor og en AI-veileder som er tilgjengelig døgnet rundt, og for å låse opp resten av Frontend Academy-kurset, kan du oppgradere til CoddyKit PRO. Kurset i Frontend Academy inneholder totalt 4 leksjoner.
Hva lærer jeg i «Portaler for modaler og verktøytips»?
Bruk ReactDOM.createPortal til å gjengi underkomponenter i en annen DOM-node, slik at modaler og verktøytips kan unnslippe containere med overflow:hidden. Du øver på Frontend Academy med praktisk kode som du kjører direkte i nettleseren, mens en AI-veileder som er tilgjengelig døgnet rundt, svarer på spørsmålene dine mens du jobber deg gjennom leksjonen.
Trenger jeg erfaring for å begynne med Frontend Academy?
Ingen tidligere erfaring er nødvendig. Frontend Academy på CoddyKit er lagt opp for både nybegynnere og viderekomne, så De kan begynne her eller helt fra start og lære i Deres eget tempo. Dette er leksjon 3 av 4.
Hvor lang tid tar leksjonen «Portaler for modaler og verktøytips»?
De fleste CoddyKit-leksjoner tar omtrent 5–10 minutter. Hver leksjon er kort og interaktiv, slik at De gjør jevne fremskritt og kan fortsette akkurat der De slapp – både på nettet og i appen.
Kan jeg skrive og kjøre kode i denne Frontend Academy-leksjonen?
Ja. Alle Frontend Academy-leksjoner har en innebygd kodeeditor, slik at De kan skrive og kjøre ekte kode direkte i nettleseren og få umiddelbar tilbakemelding fra AI – uten lokal konfigurering.
Alle leksjonene i dette kurset
- Sammensatte komponenter med Context
- Render Props- og HOC-mønstre
- Portaler for modaler og verktøytips
- Feilgrenser