diff --git a/src/components/interactive-map.js b/src/components/interactive-map.js index 591651dd..b0d01b12 100644 --- a/src/components/interactive-map.js +++ b/src/components/interactive-map.js @@ -164,6 +164,20 @@ export default class InteractiveMap extends PureComponent { // If props.mapControls is not provided, fallback to default MapControls instance // Cannot use defaultProps here because it needs to be per map instance this._mapControls = props.mapControls || new MapControls(); + + // provide an eventManager stub until real eventManager created + const eventManagerStub = { + queue: [], + on(events, ref) { + this.queue.push({events, ref, on: true}); + }, + off(events) { + this.queue.push({events}); + }, + destroy() {} + }; + + this._eventManager = eventManagerStub; } getChildContext() { @@ -180,6 +194,16 @@ export default class InteractiveMap extends PureComponent { // Register additional event handlers for click and hover eventManager.on('mousemove', this._onMouseMove); eventManager.on('click', this._onMouseClick); + + // run stub queued action + this._eventManager.queue.forEach(({events, ref, on}) => { + if (on === true) { + eventManager.on(events, ref); + } else { + eventManager.off(events); + } + }); + this._eventManager = eventManager; this._mapControls.setOptions(Object.assign({}, this.props, { @@ -317,7 +341,7 @@ export default class InteractiveMap extends PureComponent { { visible: this._checkVisibilityConstraints(this.props), ref: this._staticMapLoaded, - children: this._eventManager ? this.props.children : null + children: this.props.children } )) ) diff --git a/test/components/map.spec.js b/test/components/map.spec.js index b7ddc9d9..957c9aee 100644 --- a/test/components/map.spec.js +++ b/test/components/map.spec.js @@ -2,6 +2,8 @@ import MapGL, {InteractiveMap} from 'react-map-gl'; import {createElement} from 'react'; import ReactTestUtils from 'react-test-renderer/shallow'; +import ReactTestRenderer from 'react-test-renderer'; +import sinon from 'sinon'; import test from 'tape-catch'; const mapboxApiAccessToken = @@ -61,3 +63,19 @@ test('InteractiveMap#call onLoad when provided', t => { }, 1000); } }); + +test('Interactive map renders children on first render', t => { + const childComponent = sinon.spy(() => null); + const child = createElement(childComponent); + const map = createElement(InteractiveMap, defaultProps, child); + try { + ReactTestRenderer.create(map); + } catch (e) { + // we use try catch here as InteractiveMap fails in DidMount + // but having that render have already called this fail does not matter + // for this test + } + + t.ok(childComponent.called, 'Child rendered'); + t.end(); +});