三分钟掌握 React Portals 它是什么?为什么?如何使用?何时使用?作用域 + 冒泡 基本示例(模态框) 一个简单示例 注释 就是这样!

2025-06-07

3分钟内构建 React Portal

它是什么?

为什么?

如何?

何时使用?

作用域 + 冒泡

基本示例(模态)

一个愚蠢的例子

笔记

就是这样!

掌握这个超棒的 AP​​I,在创建 Portal 时摆脱 DOM 限制 🕹😎

它是什么?

用于渲染应用程序 DOM 层次结构之外的组件的 API。

ReactDOM.createPortal(<Component/>, DOMElement)
Enter fullscreen mode Exit fullscreen mode
直观的 API

对于那些在TL;DR阵营中的人,请向下滚动以查看演示!

为什么?

非常适合样式限制元素的场景CSS。例如 stacking( z-index) 和overflow问题。你甚至可以用新的 来渲染window!😎

链接至 HackerNoon 文章

如何?

不要在组件的方法中返回元素render,而是返回门户。

const Outsider = () => ReactDom.createPortal(<div>I am outside</div>, document.body)

const App = () => <Outsider/>
Enter fullscreen mode Exit fullscreen mode

Outsiderdocument.body呈现为👍 的直系后代

何时使用?

  • 情态动词
  • 工具提示
  • 浮动菜单
  • 小部件

作用域 + 冒泡

Portal 的一个亮点在于,在 Portal 中渲染的组件看起来就像仍在 React 树中一样。它的行为就像一个普通的 React 子组件。传递它props,它就会对更新做出反应,等等。

门户中触发的事件也会通过React树向上冒泡!查看React文档中的示例。

链接至 React 文档

基本示例(模态)

让我们从一个常见的用例开始——Modal。Modal 是一个很好的例子,我们可能需要在当前 DOM 结构之外渲染组件。

我们Modal将根据state应用程序中的值进行呈现。

const Modal = ({ children, onClose, open }) =>
  open
    ? ReactDOM.createPortal(
      <div className='modal'>
        <button className='modal__close' onClick={onClose}>&times;</button>
        { children }
      </div>,
      document.body
    )
  : null
Enter fullscreen mode Exit fullscreen mode

在我们的示例中,我们将Modal在 上渲染document.body。我们的Modal是一个函数组件,它接受childrenonCloseopen作为props

它正在发挥作用!

一个愚蠢的例子

还记得电子游戏“传送门”吗?

链接至 Portal 视频游戏维基百科文章

让我们创建一个场景😅

让我们从Man🏃开始。我们将使用GreensockDraggable创建一个可拖动的Man

链接至 GreenSock 的 Draggable 文档

现在让我们创建一个带有“传送门”的场景。我们的人物将被绑定到应用程序容器中。

const App = () => (
  <Fragment>
    <Man bounds={rootNode} />
    <div className="portal portal--in"/>
  </Fragment>
)
Enter fullscreen mode Exit fullscreen mode

这给了我们

可拖动人形概念,其中人形组件绑定到容器

现在让我们ReactDOM.createPortal参与进来😃

DOM我们在应用程序外部添加了一个元素( #outside)。我们还创建了state用于跟踪我们的元素是否Man在应用程序容器内或容器外的元素。

然后我们使用来渲染createPortala 。如果是,我们将使用来渲染我们 的外部元素👍Portal#outsideoutsidetruecreatePortalMan

<Man
  bounds={outside ? outsideElement : rootNode}
  onRelease={onRelease}
  outside={outside}
/>
<div className="portal portal--in" ref={innerPortalRef} />
{createPortal(
  <div ref={outerPortalRef} className="portal portal--out" />,
  outsideElement
)}
Enter fullscreen mode Exit fullscreen mode
const ManRender = () => (
  <div className="man" ref={manRef} role="img">
    🏃
  </div>
);

return outside ? createPortal(<ManRender />, bounds) : <ManRender />;
Enter fullscreen mode Exit fullscreen mode

Man现在,我们也会调用一个onRelease函数。这会在释放鼠标时检查光标位置是否与传送门边界相符。如果我们在传送门上方释放鼠标,则会切换该state值。所有代码都在演示中,内容不多👍

工作门户的剪辑。Man 组件可以通过虚构门户拖入或拖出应用容器。

如果你使用开发工具检查 DOM,你会看到渲染在外部发生#app👍

笔记

就是这样!

3 分钟介绍 React 中的门户!

链接到门户上的 React 文档

一如既往,如果您有任何问题或建议,请随时留言或发推文给我🐦!如果您能在社交媒体上与我联系,我将不胜感激😎

文章来源:https://dev.to/jh3y/react-portals-in-3-minutes-2g3g
PREV
为自己写作,这样有一天你才能为你敬仰的人写作。你应该开始写作吗?你够优秀吗?你应该为谁写作?你应该把文章放在哪里?你应该写些什么?我的风格是什么?有人写过这个主题吗?有人会关注吗?我应该什么时候发布?会有人读吗?我该如何为 super-cool-site.com 写作?就是这样!
NEXT
5 分钟学会 React Hooks 它们是什么? 👟 useState 为什么不使用 class? 📗 其他 Hooks useEffect 关注点分离 创建自定义 Hooks 注意事项 👍 注意事项 👎 注意事项 ⚠️ 就是这样!