Using React Portals for Drag & Drop UI
Learning about createPortal to build detachable panels and draggable elements in my video editor.
Using React Portals for Drag & Drop UI
Today I learned about a powerful feature in React that solves a very specific problem I've been facing in my Open Source Video Editor project: ReactDOM.createPortal.
The Problem: Stacking Contexts
In a complex video editor UI, you have a Timeline, a Canvas, and various Sidebar panels. When implementing drag-and-drop, you often run into z-index and overflow: hidden issues.
If I try to drag an element out of the Sidebar and onto the Canvas, but the Sidebar has overflow: hidden (to handle scrolling), the dragged element will be clipped. It visually "disappears" as it leaves the Sidebar.
The Solution: Portals
createPortal allows you to render a child component into a DOM node that exists outside the DOM hierarchy of the parent component.
1import { createPortal } from 'react-dom';2
3function DraggableOverlay({ children }) {4 // Render into the document body, breaking out of any parent overflow5 return createPortal(6 <div className="fixed z-50 pointer-events-none">7 {children}8 </div>,9 document.body10 );11}Application in the Video Editor
I plan to use this for three key features:
-
Draggable Assets: When a user drags a video clip from the asset library, the "ghost" image will be rendered in a Portal. This ensures it floats above everything else—Timeline, Canvas, Headers—regardless of the nesting or z-index of those containers.
-
Detachable Panels: I can create a "Picture-in-Picture" mode for the preview player. By toggling a state, I can move the Player component into a Portal rooted at
document.body, effectively detaching it from the layout grid and making it a floating window. -
Context Menus: Custom right-click menus often get clipped by their parent containers. Portals ensure they always render on top and are positioned relative to the viewport.
Conclusion
Portals are an escape hatch from the strict DOM hierarchy. While they should be used sparingly to avoid event bubbling confusion, they are the perfect tool for overlays, modals, and complex drag-and-drop interactions.