mirror of
https://github.com/visgl/react-map-gl.git
synced 2026-01-18 15:54:22 +00:00
marker component perf (#949)
This commit is contained in:
parent
ec129a09b2
commit
4af4183ee6
@ -21,6 +21,41 @@ class Map extends Component {
|
||||
}
|
||||
```
|
||||
|
||||
Performance notes: if a large number of markers are needed, it's generally favorable to cache the `<Marker>` nodes, so that we don't rerender them when the viewport changes.
|
||||
|
||||
```js
|
||||
import React, {Component} from 'react';
|
||||
import ReactMapGL, {Marker} from 'react-map-gl';
|
||||
|
||||
const CITIES = [...];
|
||||
|
||||
// React.memo ensures that the markers are only rerendered when data changes
|
||||
const Markers = React.memo(({data}) =>
|
||||
data.map(
|
||||
city => <Marker key={city.name} longitude={city.longitude} latitude={city.latitude} ><img src="pin.png" /></Marker>
|
||||
)
|
||||
);
|
||||
|
||||
class Map extends Component {
|
||||
state = {
|
||||
viewport: {
|
||||
latitude: 37.78,
|
||||
longitude: -122.41,
|
||||
zoom: 8
|
||||
}
|
||||
};
|
||||
|
||||
render() {
|
||||
return (
|
||||
<ReactMapGL {...this.state.viewport} onViewportChange={viewport => this.setState({viewport})}>
|
||||
<Markers data={CITIES} />
|
||||
</ReactMapGL>
|
||||
);
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
|
||||
## Properties
|
||||
|
||||
##### `latitude` {Number} (required)
|
||||
|
||||
@ -35,6 +35,8 @@ export default class App extends Component {
|
||||
bearing: 0,
|
||||
pitch: 0
|
||||
},
|
||||
// Perf: the markers never change, avoid rerender when interacting with the map
|
||||
markers: CITIES.map(this._renderCityMarker),
|
||||
popupInfo: null
|
||||
};
|
||||
}
|
||||
@ -71,7 +73,7 @@ export default class App extends Component {
|
||||
}
|
||||
|
||||
render() {
|
||||
const {viewport} = this.state;
|
||||
const {viewport, markers} = this.state;
|
||||
|
||||
return (
|
||||
<MapGL
|
||||
@ -82,7 +84,7 @@ export default class App extends Component {
|
||||
onViewportChange={this._updateViewport}
|
||||
mapboxApiAccessToken={TOKEN}
|
||||
>
|
||||
{CITIES.map(this._renderCityMarker)}
|
||||
{markers}
|
||||
|
||||
{this._renderPopup()}
|
||||
|
||||
|
||||
@ -54,6 +54,8 @@ export default class Marker extends DraggableControl<MarkerProps> {
|
||||
static propTypes = propTypes;
|
||||
static defaultProps = defaultProps;
|
||||
|
||||
_control: any = null;
|
||||
|
||||
_getPosition(): [number, number] {
|
||||
const {longitude, latitude, offsetLeft, offsetTop} = this.props;
|
||||
const {dragPos, dragOffset} = this.state;
|
||||
@ -71,26 +73,41 @@ export default class Marker extends DraggableControl<MarkerProps> {
|
||||
}
|
||||
|
||||
_render() {
|
||||
const {className, draggable} = this.props;
|
||||
const {dragPos} = this.state;
|
||||
|
||||
const [x, y] = this._getPosition();
|
||||
const transform = `translate(${x}px, ${y}px)`;
|
||||
const div = this._containerRef.current;
|
||||
|
||||
const containerStyle = {
|
||||
position: 'absolute',
|
||||
left: x,
|
||||
top: y,
|
||||
cursor: draggable ? (dragPos ? 'grabbing' : 'grab') : 'auto'
|
||||
};
|
||||
if (this._control && div) {
|
||||
// Perf: avoid rerendering if only the viewport changed
|
||||
div.style.transform = transform;
|
||||
} else {
|
||||
const {className, draggable} = this.props;
|
||||
const {dragPos} = this.state;
|
||||
|
||||
return (
|
||||
<div
|
||||
className={`mapboxgl-marker ${className}`}
|
||||
ref={this._containerRef}
|
||||
style={containerStyle}
|
||||
>
|
||||
{this.props.children}
|
||||
</div>
|
||||
);
|
||||
const containerStyle = {
|
||||
position: 'absolute',
|
||||
left: 0,
|
||||
top: 0,
|
||||
transform,
|
||||
cursor: draggable ? (dragPos ? 'grabbing' : 'grab') : 'auto'
|
||||
};
|
||||
|
||||
this._control = (
|
||||
<div
|
||||
className={`mapboxgl-marker ${className}`}
|
||||
ref={this._containerRef}
|
||||
style={containerStyle}
|
||||
>
|
||||
{this.props.children}
|
||||
</div>
|
||||
);
|
||||
}
|
||||
return this._control;
|
||||
}
|
||||
|
||||
render() {
|
||||
// invalidate cached element
|
||||
this._control = null;
|
||||
return super.render();
|
||||
}
|
||||
}
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user