My Little World

对话框

使用React Portals

React 16.3 新引入的 API
可以将虚拟 DOM 映射到任何真实 DOM 节点
解决了漂浮层的问题,比如Dialog,Tooltip 等

主要思路使用ReactDOM.createPortal将自定义dialog利用id挂到根标签上,dialog样式(包括悬浮)自己需要通过css定义,弹窗的显示和隐藏通过state操作

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
mport React from "react";
import ReactDOM from "react-dom";
import { Button } from "antd";
import "./PortalSample.css";

export default class PortalSample extends React.PureComponent {
state = { visible: false };
renderButton() {
return (
<Button type="primary" onClick={() => this.setState({ visible: true })}>
打开对话框
</Button>
);
}
renderDialog() {
return (
<div className="portal-sample">
<div>这是一个对话框!</div>
<br />
<Button
type="primary"
onClick={() => this.setState({ visible: false })}
>
关闭对话框
</Button>
</div>
);
}
render() {
if (!this.state.visible) return this.renderButton();
return ReactDOM.createPortal(
this.renderDialog(),
document.getElementById("dialog-container"),//在APP组件中定义
);
}
}
1
2
3
4
5
6
7
8
9
10
11
12
13
.portal-sample {
position: absolute;
padding: 20px;
width: 500px;
height: 300px;
left: 50%;
top: 50%;
transform: translate(-50%, -50%);
background-color: #fff;
border-radius: 10px;
border: 1px solid #ddd;
box-shadow: 0px 0px 20px 2px #ddd;
}

使用UI组件库

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
import React from "react";
import ReactDOM from "react-dom";
import { Button, Modal } from "antd";
import "./PortalSample.css";

export default class PortalSample extends React.PureComponent {
state = { visible: false };
renderButton() {
return (
<Button type="primary" onClick={() => this.setState({ visible: true })}>
打开对话框
</Button>
);
}
renderDialog() {
return (
<Modal
visible={this.state.visible}
onCancel={() => this.setState({ visible: false })}
>
<div>这是一个对话框!</div>
</Modal>
);
}
render() {
return (
<div>
{this.renderButton()}
{this.renderDialog()}
</div>
);
}
}