Portals

Back

Loading concept...

πŸŒ€ React Portals: The Magic Teleportation Door

The Story of the Trapped Popup

Imagine you have a toy box. Inside the toy box, you keep all your favorite toys. Now, what if you wanted to show your balloon to someone outside your room, but the balloon is stuck inside the toy box with a tiny lid?

That’s exactly the problem React components face!

In React, every component lives inside its parent. It’s like toys in a toy box. But sometimes, a componentβ€”like a popup or a tooltipβ€”needs to appear above everything else on the screen. If it stays inside its parent, it might get hidden or cut off!

This is where Portals come in. Think of a Portal as a magic door that teleports your component to a different place in the pageβ€”while still keeping it connected to its React family.


🎯 Portal Fundamentals

What is a Portal?

A Portal is like a secret tunnel that lets a React component render somewhere else in the HTML documentβ€”not where it normally belongs.

Normal Rendering:
β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
β”‚ Parent Component    β”‚
β”‚  β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” β”‚
β”‚  β”‚ Child (Modal)  β”‚ β”‚  ← Stuck inside!
β”‚  β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ β”‚
β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜

With Portal:
β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
β”‚ Parent Component    β”‚
β”‚  (Portal magic!)    β”‚
β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜

β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
β”‚ Modal (teleported!) β”‚  ← Now at the top!
β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜

Why Do We Need Portals?

Problem: CSS overflow: hidden or z-index issues can trap your popups and modals inside their parent containers.

Solution: Portals let your component escape to a different part of the DOM tree, usually directly inside <body>.

Key Concept

Even though a Portal renders somewhere else in the DOM, it still behaves like a normal React child:

  • βœ… It can access the same context
  • βœ… Events bubble up through the React tree
  • βœ… State and props work normally

πŸ› οΈ The createPortal API

How to Create a Portal

React gives you a special function called createPortal. It’s like saying: β€œTake this component and put it over there!”

import { createPortal } from 'react-dom';

function MyModal({ children }) {
  return createPortal(
    children,
    document.body
  );
}

The Recipe (Two Ingredients)

graph TD A["createPortal"] --> B["What to render"] A --> C["Where to render it"] B --> D["Your component/JSX"] C --> E["DOM element like document.body"]

Syntax Breakdown

createPortal(child, container)
Ingredient What It Is Example
child The React element to teleport <div>Hello!</div>
container The DOM node destination document.body

Complete Example: A Simple Modal

import { createPortal } from 'react-dom';

function Modal({ isOpen, onClose, children }) {
  if (!isOpen) return null;

  return createPortal(
    <div className="modal-overlay">
      <div className="modal-box">
        {children}
        <button onClick={onClose}>
          Close
        </button>
      </div>
    </div>,
    document.body
  );
}

Usage:

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

  return (
    <div>
      <button onClick={() =>
        setShowModal(true)}>
        Open Modal
      </button>

      <Modal
        isOpen={showModal}
        onClose={() =>
          setShowModal(false)}>
        <h2>I'm teleported!</h2>
      </Modal>
    </div>
  );
}

Creating a Custom Container

Sometimes you want your portal to go to a specific div, not the body:

// In your HTML:
// <div id="modal-root"></div>

function Modal({ children }) {
  const container = document.getElementById(
    'modal-root'
  );

  return createPortal(
    children,
    container
  );
}

πŸŽͺ Portal Use Cases

1. Modals & Dialogs

The most common use! Modals need to appear above everything.

function ConfirmDialog({ message, onYes }) {
  return createPortal(
    <div className="dialog">
      <p>{message}</p>
      <button onClick={onYes}>Yes</button>
    </div>,
    document.body
  );
}

2. Tooltips

Tooltips must float above all content without being clipped.

function Tooltip({ text, position }) {
  return createPortal(
    <div
      className="tooltip"
      style={{
        top: position.y,
        left: position.x
      }}>
      {text}
    </div>,
    document.body
  );
}

3. Dropdown Menus

When dropdowns are inside containers with overflow: hidden, they get cut off. Portals save the day!

function Dropdown({ items, anchorRect }) {
  return createPortal(
    <ul
      className="dropdown"
      style={{
        top: anchorRect.bottom,
        left: anchorRect.left
      }}>
      {items.map(item => (
        <li key={item.id}>
          {item.label}
        </li>
      ))}
    </ul>,
    document.body
  );
}

4. Notification Toasts

Notifications that pop up in a corner of the screen.

function Toast({ message }) {
  return createPortal(
    <div className="toast">
      {message}
    </div>,
    document.getElementById('toast-root')
  );
}

Use Cases Summary

graph TD A["Portal Use Cases"] --> B["πŸͺŸ Modals"] A --> C["πŸ’¬ Tooltips"] A --> D["πŸ“‹ Dropdowns"] A --> E["πŸ”” Notifications"] A --> F["🎨 Floating UI"] B --> G["Above all content"] C --> G D --> G E --> G F --> G

πŸŽ“ The Magic in Action

Here’s the beautiful thing: even though your Modal lives in document.body, it still acts like it’s inside your component:

function App() {
  const [count, setCount] = useState(0);

  return (
    <div>
      <p>Count: {count}</p>

      <Modal isOpen={true}>
        {/* This button still works! */}
        <button onClick={() =>
          setCount(c => c + 1)}>
          Add from Modal
        </button>
      </Modal>
    </div>
  );
}

Event bubbling works normally! Clicks inside the portal bubble up through the React component tree, not the DOM tree.


πŸš€ Quick Recap

Concept Remember This
Portal Magic door to render elsewhere
createPortal The spell: createPortal(what, where)
Use Cases Modals, tooltips, dropdowns, toasts
Superpower Escapes CSS traps while keeping React powers

πŸ’‘ Pro Tips

  1. Always have a container ready – Create a <div id="modal-root"> in your HTML.

  2. Clean up! – If you create DOM nodes dynamically, remove them when the component unmounts.

  3. Accessibility matters – Use proper ARIA attributes for modals and dialogs.

  4. Z-index is still important – Just because you portal doesn’t mean you skip z-index management!


Congratulations! πŸŽ‰ You now understand React Portals. You can teleport components anywhere on the page while keeping all the React magic intact. Go build those beautiful modals and tooltips!

Loading story...

Story - Premium Content

Please sign in to view this story and start learning.

Upgrade to Premium to unlock full access to all stories.

Stay Tuned!

Story is coming soon.

Story Preview

Story - Premium Content

Please sign in to view this concept and start learning.

Upgrade to Premium to unlock full access to all content.