React Portals 为我们提供了一种将子组件渲染到父组件 DOM 层级 之外的 DOM 节点的方法。这项功能是在 React 16.0 版本 中引入的。
在此之前,我们在 HTML 中通常只有一个 DOM 元素用于挂载整个 React 应用,也就是 public 文件夹下 index.html 中的 root 元素。基本上,我们会将 App 组件挂载到这个 root 元素上。约定俗成的做法是,使用一个 id 为 root 的 div 元素作为根 DOM 节点。如果你在浏览器中查看 DOM 树,会发现应用中的每一个 React 组件都归属于这个 root 元素,也就是位于这个标签内部。
但是,React Portals 赋予了我们打破这棵 DOM 树结构的能力,让我们可以将组件渲染到不属于 root 元素下级的 DOM 节点上。这样做打破了组件必须作为新元素并遵循父子层级关系的惯例。它们常用于模态对话框、悬浮卡片、加载器和弹出消息等场景。
语法:
ReactDOM.createPortal(child, container)
参数: 这里的第一个参数是 child(子节点),它可以是一个 React 元素、字符串或者片段;第二个参数是 container(容器),这是一个位于父组件 DOM 层级之外的 DOM 节点(或位置),我们的 portal 将被插入到这里。
引入: 要创建和使用 portal,你需要按照下面的方式引入 ReactDOM。
import ReactDOM from ‘react-dom‘;
创建 React 应用:
步骤 1: 使用以下命令创建一个 React 应用。
npx create-react-app foldername
步骤 2: 创建项目文件夹(即 foldername)后,使用以下命令进入该目录。
cd foldername
项目结构: 它将如下所示。
示例: 现在,让我们在 App.js 文件中编写以下代码。在这里,App 是我们的默认组件,我们在其中编写了代码。
App.js
CODEBLOCK_324d1496
index.html
CODEBLOCK_ee4e0773
输出:
!outputJPG格式输出
解释: 在这里,我们可以看到我们的
标签 "Portal Demo" 位于新创建的 portal DOM 节点下,而不是传统的 root DOM 节点下。这清楚地告诉我们,React Portal 是如何提供突破根 DOM 树的能力,并在父 DOM 元素之外渲染组件/元素的。
Portal 内部的事件冒泡: 虽然我们没有在父 DOM 元素内部渲染 portal,但它的行为仍然类似于应用内部的常规 React 组件。因为它仍然驻留在 DOM 树层级中,所以可以访问 props 和 state。例如,如果我们从 portal 内部触发一个事件,它会传播(冒泡)到包含它的 React 树中的父组件,也就是说,事件冒泡 的工作方式与正常情况下的相同。让我们通过另一个例子来理解这一点:
示例: 演示事件冒泡如何与 portal 一起工作的程序。在这里,我们将通过从父 DOM 节点外部触发事件监听器来更新状态的先前值。
App.js
“
import React, { Component } from ‘react‘
import ReactDOM from ‘react-dom‘
class Portal extends Component {
render() {
// 创建 portal
return ReactDOM.createPortal(
Click
,