版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/zeping891103/article/details/83998254
Portals 提供了一种很好的将子节点渲染到父组件以外的 DOM 节点的方式,API如下:
ReactDOM.createPortal(child, container)
第一个参数(child
)是任何可渲染的React的子元素,例如一个元素,字符串或碎片。第二个参数(container
)则是一个 DOM 元素。
对于 portal 的一个典型用例是当父组件有 overflow: hidden
或 z-index
样式,但却需要子组件能够在视觉上“跳出(break out)”其容器。例如,对话框、hovercards以及提示框。
demo 实现模态弹框效果:
// Modal.jsx
import React from 'react';
import ReactDOM from 'react-dom';
class Modal extends React.Component {
constructor(props) {
super(props);
this.state = {};
this.el = document.createElement('div');
}
componentDidMount() {
document.getElementById('modal-root').appendChild(this.el);
}
componentWillUnmount() {
document.getElementById('modal-root').removeChild(this.el);
}
render() {
return ReactDOM.createPortal(
this.props.children,
this.el,
);
}
}
export default Modal;
PortalsDemo.jsx
import React from 'react';
import Modal from './Modal.jsx'; // Portals 用法
import './../../css/modal.css';
class PortalsDemo extends React.Component {
constructor(props) {
super(props);
this.state = {
showModal: false
};
this.handleShow = this.handleShow.bind(this);
this.handleHide = this.handleHide.bind(this);
}
handleShow() {
this.setState({
showModal: true
});
}
handleHide() {
this.setState({
showModal: false
});
}
render() {
const modal = this.state.showModal ? (
<Modal>
<div className="modal" onClick={this.handleHide}>
<button>Hide modal</button>
</div>
</Modal>
) : null;
return(
<div className="app">
<button onClick={this.handleShow}>Show modal</button>
{modal}
</div>
);
}
}
export default PortalsDemo;
model.css
.modal {
background-color: rgba(0, 0, 0, 0.5);
position: fixed;
height: 100%;
width: 100%;
top: 0;
left: 0;
display: flex;
align-items: center;
justify-content: center;
}
App.jsx
import React from 'react';
import PortalsDemo from './components/portals/PortalsDemo.jsx'; // Portals 用法
class App extends React.Component {
constructor(props) {
super(props);
this.state = {};
}
render() {
return(
<React.Fragment>
<div id="app-root">
<PortalsDemo></PortalsDemo>
</div>
<div id="modal-root"></div>
</React.Fragment>
);
}
}
export default App;
该demo实现了PortalsDemo里的子dom节点挂载到了id为"modal-eoot"的dom节点。