8、弹窗组件
弹窗类组件的要求弹窗内容在A处声明,却在B处展示。react中相当于弹窗内容看起来被render到⼀个组件⾥⾯ 去,
实际改变的是⽹⻚上另⼀处的DOM结构。
父组件:
1 import React, { Component } from "react"; 2 import { Button } from "antd"; 3 import Dialog from "../components/Dialog"; 4 5 export default class DialogPage extends Component{ 6 constructor(props){ 7 super(props) 8 this.state={ 9 showDialog:false 10 } 11 } 12 handleShowDialog=()=>{ 13 this.setState({ 14 showDialog:!this.state.showDialog 15 }) 16 }; 17 render() { 18 const { showDialog } = this.state; 19 return ( 20 <div className="dialogPage"> 21 <h1>DialogPage</h1> 22 <Button onClick={this.handleShowDialog}>dialog toggle</Button> 23 {showDialog && ( 24 <Dialog hideDialog={this.handleShowDialog} hide={false}> 25 这是一个弹窗 26 </Dialog> 27 )} 28 </div> 29 ); 30 } 31 }
子组件:
import React,{Component} from 'react'; import {createPortal} from 'react-dom' export default class Dialog extends Component{ constructor(props){ super(props); const doc = window.document; this.node = doc.createElement("div"); doc.body.appendChild(this.node) } componentWillUnmount(){ window.document.body.removeChild(this.node); } render(){ const {hideDialog, children, hide} = this.props; console.log('children', children) let tem = hide ? 'hidden' :""; return createPortal( <div className="dialog" style={{ visibility: tem }}> {typeof hideDialog==="function" && ( <button onClick={hideDialog}>关闭弹窗</button>)} {children} </div>, this.node ) } }
dialog css样式
.dialog {
position: absolute;
top: 0;
right: 0;
bottom: 0;
left: 0;
line-height: 30px;
width: 400px;
height: 300px;
transform: translate(50%, 50%);
border: solid 1px gray;
text-align: center;
}