import React from 'react' ; import ReactDOM from 'react-dom' ; import PropTypes from 'prop-types' ; import { ownerDocument } from './../utils' ; /**
 * Portals provide a first-class way to render children into a DOM node
 * that exists outside the DOM hierarchy of the parent component.
 */ class Portal extends React . Component { componentDidMount ( ) { this . setMountNode ( this . props . container ) ; if ( ! this . props . disablePortal ) { this . forceUpdate ( ) ; } } componentDidUpdate ( prevProps ) { if ( prevProps . container !== this . props . container || prevProps . disablePortal !== this . props . disablePortal ) { this . setMountNode ( this . props . container ) ; if ( ! this . props . disablePortal ) { this . forceUpdate ( ) ; } } } componentWillUnmount ( ) { this . mountNode = null ; } setMountNode ( container ) { if ( this . props . disablePortal ) { this . mountNode = ReactDOM . findDOMNode ( this ) . parentElement ; } else { this . mountNode = getContainer ( container , getOwnerDocument ( this ) . body ) ; } } public getMountNode = ( ) => { return this . mountNode ; } ; render ( ) { const { children , disablePortal } = this . props ; if ( disablePortal ) { return children ; } return this . mountNode ? ReactDOM . createPortal ( children , this . mountNode ) : null ; } } Portal . propTypes = { /**
     * The children to render into the `container`.
     */ children : PropTypes . node . isRequired , /**
     * A node, component instance, or function that returns either.
     * The `container` will have the portal children appended to it.
     * By default, it uses the body of the top-level document object,
     * so it's simply `document.body` most of the time.
     */ container : PropTypes . oneOfType ( [ PropTypes . object , PropTypes . func ] ) , /**
     * Disable the portal behavior.
     * The children stay within it's parent DOM hierarchy.
     */ disablePortal : PropTypes . bool , } ; Portal . defaultProps = { disablePortal : false , } ; function getContainer ( container , defaultContainer ) { container = typeof container === 'function' ? container ( ) : container ; return ReactDOM . findDOMNode ( container ) || defaultContainer ; } function getOwnerDocument ( element ) { return ownerDocument ( ReactDOM . findDOMNode ( element ) ) ; } export default Portal ;