Portal 提供了将子节点渲染到父组件 DOM 层次结构之外的方法。

示例 1: 模态框

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

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

示例 2: 工具提示

这是一段包含 工具提示 的文本。鼠标悬停在带下划线的文字上查看效果。这个容器设置了 overflow: hidden,但 Tooltip 仍然能正确显示。

优势: 使用 Portal 渲染到 body, 工具提示不会被父元素的 overflow: hidden 裁剪。

示例 3: 通知系统

createPortal(
  <div className="fixed top-4 right-4">
    {notifications.map(n => (
      <Notification key={n.id} {...n} />
    ))}
  </div>,
  document.body
)

示例 4: 事件冒泡

点击这个蓝色区域(父组件)

点击记录:

暂无点击
重要: 即使 Portal 内容在 DOM 中渲染到 body, 点击事件仍会沿 React 组件树冒泡到父组件!

示例 5: 下拉菜单

这个容器有 overflow: hidden,但下拉菜单使用 Portal 渲染,不会被裁剪。