React Portals
React16.0 版本在 2017年9月中引入了React门户。 React门户提供了一种在其组件层次结构之外(即在单独的组件中)呈现元素的方法。
在React 16.0版本之前,在其父组件层次结构之外呈现子组件非常棘手。如果这样做,则会违反组件需要作为新元素呈现并遵循 parent-child 层次结构的约定。在React中,父组件总是想去其子组件所在的位置。这就是React门户概念出现的原因。
语法
ReactDOM.createPortal(child, container)
在这里,第一个参数(子级)是组件,可以是元素,字符串或片段,第二个参数(容器)是DOM元素。
React v16之前的示例
通常,当您想从组件的render方法返回一个元素时,会将它作为新的div装入到DOM中,并呈现最接近的父组件的子代。
render() {
// React mounts a new div into the DOM and renders the children into it
return (
<div>
{this.props.children}
</div>
);
}
使用门户网站的示例
但是,有时我们希望将子组件插入DOM中的其他位置。这意味着React不想创建一个新的div。我们可以通过创建React门户来做到这一点。
render() {
return ReactDOM.createPortal(
this.props.children,
myNode,
);
}
功能
它使用React版本16及其官方API创建门户。
它具有React版本15的后备功能。
它将子组件传输到新的React门户,默认情况下附加到document.body。
它也可以定位用户指定的DOM元素。
它支持服务器端渲染
它支持返回数组(不需要包装div)
它使用 <Portal />和<PortalWithState />,因此在灵活性和便利性之间没有妥协。
它不会产生任何DOM混乱。
它没有依赖关系,简约。
何时使用?
React门户的常见用例包括:
模式
工具提示
浮动菜单
小部件
安装
我们可以使用以下命令安装React Portal。
$ npm install react-portal--save
React Portal的解释
使用以下命令创建一个新的React项目。
$ npx create-react-app reactapp
打开App.js文件并插入以下代码段。
App.js
import React, {Component} from 'react';
import './App.css'
import PortalDemo from './PortalDemo.js';
class App extends Component {
render () {
return (
<div className='App'>
<PortalDemo />
</div>
);
}
}
export default App;
下一步是创建一个门户组件并将其导入App.js文件。
PortalDemo.js
import React from 'react'
import ReactDOM from 'react-dom'
function PortalDemo(){
return ReactDOM.createPortal(
<h1>Portals Demo</h1>,
document.getElementById('portal-root')
)
}
export default PortalDemo
现在,打开Index.html文件并添加
元素以访问根节点之外的子组件。
Index.html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8" />
<link rel="shortcut icon" href="%PUBLIC_URL%/favicon.ico" />
<meta name="viewport" content="width=device-width, initial-scale=1" />
<meta name="theme-color" content="#000000" />
<link rel="manifest" href="%PUBLIC_URL%/manifest.json" />
<title>React App</title>
</head>
<body>
<noscript>It is required to enable JavaScript to run this app.</noscript>
<div id="root"></div>
<div id="portal-root"></div>
</body>
</html>
输出:
执行React应用程序时,将显示以下屏幕。
现在,打开检查(Ctrl + shift + I)。在此窗口中,选择元素部分,然后单击
组件。在这里,我们可以看到每个标签都在" portal-root" DOM节点下,而不是在" root" DOM节点下。因此,我们可以看到React Portal如何提供突破根DOM树的能力。