FrontendPro

72Build a reusable React modal using portals

mediumAbout 35 minutesCodingreactportalsaccessibilityfocus

Problem

Build <Modal open={open} onClose={onClose} title="…">{children}</Modal>.

  • Render nothing when open is false.
  • When open, render into document.body with createPortal, so it escapes parents with overflow: hidden or z-index stacking.
  • Markup: a backdrop <div data-testid="backdrop"> containing <div role="dialog" aria-modal="true" aria-labelledby={titleId}> with an <h2 id={titleId}>{title}</h2>, the children, and a Close button.

Requirements

  • Pressing Escape calls onClose.
  • Clicking the backdrop calls onClose; clicking inside the dialog does not.
  • On open, move focus into the dialog (the dialog element itself, with tabIndex={-1}). On close, return focus to the element that was focused before it opened.
  • Prevent the page behind from scrolling while open (document.body.style.overflow = "hidden"), and restore the previous value on close.
  • Two modals on the page must have different title ids.

Try it yourself

Write your solution, run it, then submit to check it against the tests.

App.jsxReact + DOM

Step-by-step

createPortal(jsx, document.body) renders the DOM elsewhere while keeping the React tree where it is: context, state and event bubbling through React still work as if the modal were inside its parent.

Unlock the full solution

What's inside

  • Step-by-step
  • Approach
  • Solution
  • Complexity
  • Edge cases
  • Follow-up questions
  • Tests

Includes 2 code listings, 5 edge cases, 4 follow-up questions.

One-time payment by UPI, card or net banking. Launch price.

All 150 answersOne payment, yours forever