React学习笔记(五) Portal
1、用法
普通的组件,子组件的元素将挂载到父组件的DOM节点中。
render() {
// React 挂载一个div节点,并将子元素渲染在节点中
return (
<div>
{this.props.children}
</div>
);
}
有时需要将元素渲染到DOM中的不同位置上去,这是就用到的portal的方法。
render(){
// 此时React不再创建div节点,而是将子元素渲染到Dom节点上。domNode,是一个有效的任意位置的dom节点。
return ReactDOM.createPortal(
this.props.children,
domNode
)
}
一个典型的用法就是当父组件的dom元素有 overflow:hidden或者z-inde样式,而你又需要显示的子元素超出父元素的盒子。举例来说,如对话框,悬浮框,和小提示。
2、在protal中的事件冒泡
虽然通过portal渲染的元素在父组件的盒子之外,但是渲染的dom节点仍在React的元素树上,在那个dom元素上的点击事件仍然能在dom树中监听到。
//index.jsx
import React, { Component } from 'react'
import { createPortal } from 'react-dom'
import Dialog from './Dialog'
class PortalDemo extends Component {
state = {
show: false
}
open = () => {
this.setState({
show: true
})
}
close = () => {
console.log(0)
this.setState({
show: false
})
}
render() {
return (
<>
<div onClick={this.close}>
{
this.state.show && <Dialog></Dialog>
}
</div>
<button onClick={this.open}>open</button>
</>
);
}
}
class PortalDialog extends Component {
render() {
return createPortal(
<PortalDemo></PortalDemo>,
document.body
)
}
}
export default PortalDialog;
//Dialog.jsx
import React, { Component } from 'react';
class Dialog extends Component {
render() {
return (
<div
style={{
position: 'fixed',
left: 0,
right: 0,
top: 0,
bottom: 0,
background: 'rgba(0, 0, 0, 0.5)',
display: 'flex',
justifyContent: 'center',
alignItems: 'center'
}}
>
dialog
</div>
);
}
}
export default Dialog;

浙公网安备 33010602011771号