72Build a reusable React modal using portals
mediumAbout 35 minutesCodingreactportalsaccessibilityfocus
Problem
Build <Modal open={open} onClose={onClose} title="…">{children}</Modal>.
- Render nothing when
openis false. - When open, render into
document.bodywithcreatePortal, so it escapes parents withoverflow: hiddenorz-indexstacking. - 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
EscapecallsonClose. - 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.