打算用React写对话框已经很长一段时间,现在是时候兑现承诺了。实际上,写起来相当简单。
核心在于使用React的接口React.createPortal(element, domContainer)
。该接口将element
渲染后的DOM节点嵌入domContainer
(通常是document.body
),并保证只嵌入一次。
所以,我们可以这样写一个对话框或模态框:
- function Dialog() {
- return React.createPortal( <div>Dialog contents</div>, document.body )
- }
一个新的div
会出现在body
内部:

一个完整DEMO:

点击运行DEMO
- class Modal extends React.Component {
- render() {
- const {
- visible,
- onClose
- } = this.props
- return visible && ReactDOM.createPortal(<StyledModalRoot>
- <div className="box">
- Content
- <br/>
- <button onClick={onClose}>Close</button>
- </div>
- </StyledModalRoot>, document.body)
- }
- }
-
- class App extends React.Component {
- state = {
- visibleModal: false
- }
- showModal = () => this.setState( { visibleModal: true } )
- handleCloseModal = () => this.setState( { visibleModal: false } )
- render() {
- const { visibleModal } = this.state
- return <div style={{padding: '20px'}}>
- <button onClick={ this.showModal }>Show Modal</button>
- <Modal visible={visibleModal} onClose={ this.handleCloseModal } />
- </div>
- }
- }
-
- const StyledModalRoot = styled.div`
- position: fixed;
- z-index: 1001;
- left: 0;
- top: 0;
- display: grid;
- place-items: center;
- width: 100%;
- height: 100%;
- background: rgba( 0, 0, 0, 0.2 );
-
- >.box {
- position: relative;
- display: grid;
- place-items: center;
- width: 80%;
- height: 80%;
- background: white;
- border-radius: 10px;
- box-shadow: 0px 3px 5px -1px rgba(0,0,0,0.2), 0px 5px 8px 0px rgba(0,0,0,0.14), 0px 1px 14px 0px rgba(0,0,0,0.12);
- }
- `
以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持w3xue。