From 45ecda13e6a91a20ca683aca89bce30eaf4c8bf5 Mon Sep 17 00:00:00 2001 From: Artem Artemyev Date: Tue, 18 Dec 2018 21:02:16 +0500 Subject: [PATCH] Added React 16 createPortal with backwards compatibility (#696) * added react 16 createPortal support with backwards compatibility * fixed lint errors --- src/google_map.js | 63 ++++++++++++++++++++++++++++++----------------- 1 file changed, 40 insertions(+), 23 deletions(-) diff --git a/src/google_map.js b/src/google_map.js index ab8db39..1c418ae 100644 --- a/src/google_map.js +++ b/src/google_map.js @@ -38,6 +38,11 @@ const DEFAULT_MIN_ZOOM = 3; // Starting with version 3.32, the maps API calls `draw()` each frame during // a zoom animation. const DRAW_CALLED_DURING_ANIMATION_VERSION = 32; +const IS_REACT_16 = ReactDOM.createPortal !== undefined; + +const createPortal = IS_REACT_16 + ? ReactDOM.createPortal + : ReactDOM.unstable_renderSubtreeIntoContainer; function defaultOptions_(/* maps */) { return { @@ -240,7 +245,7 @@ export default class GoogleMap extends Component { this.zoomAnimationInProgress_ = false; this.state = { - overlayCreated: false, + overlay: null, }; } @@ -478,6 +483,21 @@ export default class GoogleMap extends Component { }); }; + _renderPortal = () => ( + + ); + _initMap = () => { // only initialize the map once if (this.initialized_) { @@ -593,7 +613,6 @@ export default class GoogleMap extends Component { : '2000px'; const div = document.createElement('div'); - this.div = div; div.style.backgroundColor = 'transparent'; div.style.position = 'absolute'; div.style.left = '0px'; @@ -616,30 +635,26 @@ export default class GoogleMap extends Component { maps, overlay.getProjection() ); - ReactDOM.unstable_renderSubtreeIntoContainer( - this_, - , - div, - // remove prerendered markers - () => this_.setState({ overlayCreated: true }) - ); + + if (!IS_REACT_16) { + createPortal( + this_, + this_._renderPortal(), + div, + // remove prerendered markers + () => this_.setState({ overlay: div }) + ); + } else { + this_.setState({ overlay: div }); + } }, onRemove() { - if (this.div) { - ReactDOM.unmountComponentAtNode(this.div); + const renderedOverlay = this_.state.overlay; + if (renderedOverlay && !IS_REACT_16) { + ReactDOM.unmountComponentAtNode(renderedOverlay); } + this_.setState({ overlay: null }); }, draw() { @@ -1077,7 +1092,8 @@ export default class GoogleMap extends Component { }; render() { - const mapMarkerPrerender = !this.state.overlayCreated + const overlay = this.state.overlay; + const mapMarkerPrerender = !overlay ? + {IS_REACT_16 && overlay && createPortal(this._renderPortal(), overlay)} {/* render markers before map load done */} {mapMarkerPrerender}