createPortal
一、认识
ReactDOM.createPortal()
传送门,用于创建portal
。Portal
将提供一种将子节点渲染到DOM
节点中的方式,该节点存在于DOM
组件的层次结构之外。portal
只改变 DOM
节点的所处位置。在其他方面,渲染至 portal
的 JSX
的行为表现与作为 React
组件的子节点一致。该子节点可以访问由父节点树提供的 context
对象、事件将从子节点依循 React
树冒泡到父节点。
二、语法
import { createPortal } from 'react-dom';
function App(){
return <div>
<div>按钮</div>
{
createPortal(children, domNode, key?)
}
</div>
}
-
children
:React
可以渲染的任何内容,如 JSX
片段(<div />
或<SomeComponent />
等等)、Fragment
(<>...</>
)、字符串或数字,以及这些内容构成的数组。 -
domNode
: 某个已经存在的DOM
节点,例如由document.getElementById()
返回的节点。在更新过程中传递不同的DOM
节点将导致portal
内容被重建。 -
key
: 用作portal key
的独特字符串或数字。
三、返回值
createPortal
返回一个可以包含在 JSX
中或从 React
组件中返回的 React
节点。如果 React
在渲染输出中遇见它,它将把提供的 children
放入提供的 domNode 中。
四、应用场景
4.1 Model 弹窗
class
组件写法
import React from "react";
import { createPortal } from "react-dom";
export default class MyDialog extends React.Component {
constructor(props) {
super(props);
if (!this.node) {
this.node = document.createElement("div");
this.node.classList = ["my-dialog"];
document.body.appendChild(this.node);
}
}
componentWillUnmount() {
this.node && this.node.remove();
}
render(){
return createPortal(<div>我的弹窗</div>,this.node);
}
}
hooks
组件写法
import React, { useEffect } from "react";
import { createPortal } from "react-dom";
export default function MyDialog() {
let node = document.createElement("div");
node.classList = ["my-dialog"];
document.body.appendChild(node);
useEffect(() => {
return () => {
node && node.remove();
};
}, []);
return createPortal(<div>我的弹窗</div>, node);
}