Fix of Interactive map always needs a double render to render children (#413)

This commit is contained in:
Ivan Starkov 2017-11-28 01:07:53 +03:00 committed by Xiaoji Chen
parent 93901ce698
commit 128f72f769
2 changed files with 43 additions and 1 deletions

View File

@ -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
}
))
)

View File

@ -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();
});