ReactJS 门户
React 门户提出了一种将子级渲染到DOM节点中的方法,该 DOM 节点出现在父组件的DOM 层次结构之外。门户是在React 16.0 版本中引入的。
到目前为止,我们在安装我们的 react 应用程序的 HTML 中有一个 DOM 元素,即我们的index.html的根元素在 public 文件夹中。基本上,我们将App组件安装到我们的根元素上。将 id 为root的 div 元素用作根 DOM 元素几乎是一种惯例。如果你看一下 DOM 树中的浏览器,我们应用程序中的每个 React 组件都属于根元素,即在这个语句中。
但是 React Portal 为我们提供了跳出这个 dom 树并将组件渲染到不在这个根元素下的 dom 节点上的能力。这样做打破了组件需要呈现为新元素并遵循父子层次结构的约定。它们通常用于模态对话框、悬停卡、加载器和弹出消息。
句法:
ReactDOM.createPortal(child, container)
参数:这里的第一个参数是一个子元素,可以是 React 元素、字符串或片段,第二个参数是一个容器,它是位于我们门户所在的父组件的 DOM 层次结构之外的 DOM 节点(或位置)是要插入的。
导入:要创建和使用门户,您需要导入ReactDOM ,如下所示。
import ReactDOM from 'react-dom';
创建反应应用程序:
第 1 步:使用以下命令创建一个React 应用程序。
npx create-react-app foldername
第 2 步:创建项目文件夹(即文件夹名称)后,使用以下命令移动到该文件夹。
cd foldername
项目结构:它将如下所示。
示例:现在在 App.js 文件中写下以下代码。在这里,App 是我们编写代码的默认组件。
App.js
import ReactDOM from 'react-dom'
function App() {
// Creating a portal
return ReactDOM.createPortal(
Portal demo
,
document.getElementById('portal')
)
}
export default App;
index.html
React App
App.js
import React, { Component } from 'react'
import ReactDOM from 'react-dom'
class Portal extends Component {
render() {
// Creating portal
return ReactDOM.createPortal(
,
document.getElementById('portal')
);
}
}
class App extends Component {
constructor(props) {
super(props);
// Set initial state
this.state = {click: 0};
// Binding this keyword
this.handleClick = this.handleClick.bind(this);
}
handleClick() {
// This will trigger when the button inside Portal
// is clicked, It updates Parent's state, even though it
// is not rendered inside the parent DOM element
this.setState(prevState => ({
click: prevState.click + 1
}));
}
render() {
return (
You have clicked me {this.state.click} times
);
}
}
export default App;
index.html
React App
索引.html
React App
输出:
说明:在这里,我们可以看到我们的
标签Portal Demo是在新创建的Portal DOM 节点下,而不是传统的根DOM 节点。它清楚地告诉我们 React Portal 如何提供突破根 DOM 树并在父 DOM 元素之外呈现组件/元素的能力。
入口内的事件冒泡:虽然我们没有在父 DOM 元素内渲染入口,但它的行为仍然类似于应用程序内的常规 React 组件。它可以访问属性和状态,因为它位于 DOM 树层次结构中。例如,如果我们从门户内部触发一个事件,它将传播到包含 React 树中的父组件,即事件冒泡的工作方式与正常情况下相同。让我们用另一个例子来理解这一点:
示例:演示事件冒泡如何与门户一起使用的程序。在这里,我们将通过从父 DOM 节点外部触发事件侦听器来更新状态的先前值。
应用程序.js
import React, { Component } from 'react'
import ReactDOM from 'react-dom'
class Portal extends Component {
render() {
// Creating portal
return ReactDOM.createPortal(
,
document.getElementById('portal')
);
}
}
class App extends Component {
constructor(props) {
super(props);
// Set initial state
this.state = {click: 0};
// Binding this keyword
this.handleClick = this.handleClick.bind(this);
}
handleClick() {
// This will trigger when the button inside Portal
// is clicked, It updates Parent's state, even though it
// is not rendered inside the parent DOM element
this.setState(prevState => ({
click: prevState.click + 1
}));
}
render() {
return (
You have clicked me {this.state.click} times
);
}
}
export default App;
索引.html
React App
输出:
说明:我们创建了一个初始值为 0 的状态计数和一个函数handleClick ,它将先前的状态值增加 1。当我们单击已在根DOM 节点之外呈现的按钮时,后者作为onClick 事件被触发.即使这样,它也能够将事件传播到父组件并访问状态值,就好像它是一个常规的 React 组件一样。
参考链接: https://reactjs.org/docs/portals.html