Skip to content

Commit a66ade9

Browse files
committed
use ReactDOM.createPortal if it is available
1 parent d53bc20 commit a66ade9

File tree

1 file changed

+39
-12
lines changed

1 file changed

+39
-12
lines changed

src/Portal.js

Lines changed: 39 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,9 @@ import ownerDocument from './utils/ownerDocument';
1111
* You can think of it as a declarative `appendChild()`, or jQuery's `$.fn.appendTo()`.
1212
* The children of `<Portal/>` component will be appended to the `container` specified.
1313
*/
14+
15+
const useCreatePortal = ReactDOM.createPortal !== undefined;
16+
1417
class Portal extends React.Component {
1518

1619
static displayName = 'Portal';
@@ -26,9 +29,21 @@ class Portal extends React.Component {
2629
])
2730
};
2831

32+
componentWillMount(){
33+
if (useCreatePortal){
34+
this._mountOverlayTarget();
35+
}
36+
}
37+
2938
componentDidMount() {
3039
this._isMounted = true;
3140
this._renderOverlay();
41+
if (useCreatePortal){
42+
this._portalContainerNode = getContainer(this.props.container, ownerDocument(this).body);
43+
if (this._overlayTarget) {
44+
this._portalContainerNode.appendChild(this._overlayTarget);
45+
}
46+
}
3247
}
3348

3449
componentDidUpdate() {
@@ -45,39 +60,44 @@ class Portal extends React.Component {
4560

4661
componentWillUnmount() {
4762
this._isMounted = false;
48-
this._unrenderOverlay();
63+
if (!useCreatePortal){
64+
this._unrenderOverlay();
65+
}
4966
this._unmountOverlayTarget();
5067
}
5168

5269

5370
_mountOverlayTarget = () => {
5471
if (!this._overlayTarget) {
5572
this._overlayTarget = document.createElement('div');
56-
this._portalContainerNode = getContainer(this.props.container, ownerDocument(this).body);
57-
this._portalContainerNode.appendChild(this._overlayTarget);
73+
if (!useCreatePortal){
74+
this._portalContainerNode = getContainer(this.props.container, ownerDocument(this).body);
75+
this._portalContainerNode.appendChild(this._overlayTarget);
76+
}
5877
}
5978
}
6079

6180
_unmountOverlayTarget = () => {
62-
if (this._overlayTarget) {
81+
if (this._overlayTarget && this._portalContainerNode) {
6382
this._portalContainerNode.removeChild(this._overlayTarget);
64-
this._overlayTarget = null;
6583
}
84+
this._overlayTarget = null;
6685
this._portalContainerNode = null;
6786
}
6887

6988
_renderOverlay = () => {
70-
7189
let overlay = !this.props.children
7290
? null
7391
: React.Children.only(this.props.children);
7492

7593
// Save reference for future access.
7694
if (overlay !== null) {
77-
this._mountOverlayTarget();
78-
this._overlayInstance = ReactDOM.unstable_renderSubtreeIntoContainer(
79-
this, overlay, this._overlayTarget
80-
);
95+
if (!useCreatePortal){
96+
this._mountOverlayTarget();
97+
this._overlayInstance = ReactDOM.unstable_renderSubtreeIntoContainer(
98+
this, overlay, this._overlayTarget
99+
);
100+
}
81101
} else {
82102
// Unrender if the component is null for transitions to null
83103
this._unrenderOverlay();
@@ -93,7 +113,12 @@ class Portal extends React.Component {
93113
}
94114

95115
render() {
96-
return null;
116+
if (useCreatePortal && this.props.children) {
117+
let overlay = React.Children.only(this.props.children);
118+
return ReactDOM.createPortal(overlay, this._overlayTarget);
119+
} else {
120+
return null;
121+
}
97122
}
98123

99124
getMountNode = () => {
@@ -104,7 +129,9 @@ class Portal extends React.Component {
104129
if (!this._isMounted) {
105130
throw new Error('getOverlayDOMNode(): A component must be mounted to have a DOM node.');
106131
}
107-
132+
if (useCreatePortal){
133+
return ReactDOM.findDOMNode(this);
134+
}
108135
if (this._overlayInstance) {
109136
return ReactDOM.findDOMNode(this._overlayInstance);
110137
}

0 commit comments

Comments
 (0)