react-map-gl/docs/get-started/interactivity.md

3.0 KiB

Interactivity

Being a stateless component, the <MapGL> instance won't change what's shown in its viewport unless it receives new props.

To update the <MapGL> component's viewport, use the onChangeViewport callback. A viewport object includes the set of props that determines what to show in the map so if you're using JSX, the following...

<MapGL
  width={' + this.state.map.width + '}
  height={' + this.state.map.height + '}
  latitude={' + d3.round(this.state.map.latitude, 3) + '}
  longitude={' + d3.round(this.state.map.longitude, 3) + '}
  zoom={' + d3.round(this.state.map.zoom, 3) + '}
  mapStyle={mapStyle} />

is equivalent to...'}),

<MapGL {...viewport} mapStyle={mapStyle} />

assuming that...

var viewport = {
  width: ' + this.state.map.width + ',
  height: ' + this.state.map.height + ',
  latitude: ' + d3.round(this.state.map.latitude, 3) + ',
  longitude: ' + d3.round(this.state.map.longitude, 3) + ',
  zoom: ' + d3.round(this.state.map.zoom, 3) + '
  };'

To support panning and zooming, pass a callback function as the onChangeViewport prop.

TODO - interactive example

r(MapGL, assign({onChangeViewport: this._onChangeViewport},
  this.state.map), [
    r(Attribute, this.state.map)
  ]
),
render() {
  var {viewport} = this.state;
  return <MapGL
    {...viewport}
    onChangeViewport={viewport => this.setState({viewport})}
  />;
}

Alternatively, to prevent the component from being interactive, don't pass it an onChangeViewport() callback.

TODO - Interactive Example

      r(MapGL, assign({}, this.state.map, {height: 200}), [
        r(Attribute, assign({}, this.state.map, {height: 200}))
      ]),

The viewport object returned from onChangeViewport() also includes two other important pieces of state. They're isDragging and startDragLngLat. To support typical interactive usecases, pass them back as props to the component. The component works this way to be stateless.' }),

Complete example Here's a complete example you can copy and paste into your own project.'

var assign = require('object-assign');
var MapGL = require('react-map-gl');
var React = require('react');
var Immutable = require('immutable');
var rasterTileStyle = require('raster-tile-style');

var InteractiveMap = React.createClass({
  getInitialState() {
    var tileSource = '//tile.stamen.com/toner/{z}/{x}/{y}.png';
    var mapStyle = Immutable.fromJS(rasterTileStyle([tileSource]));
    return {
      viewport: {
        latitude: 37.78,
        longitude: -122.45,
        zoom: 11,
        width: 800,
        height: 800,
        startDragLngLat: null,
        isDragging: null
      },
      mapStyle: mapStyle
    };
  },

  _onChangeViewport(newViewport) {
    var viewport = assign({}, this.state.viewport, newViewport);
    this.setState({viewport});
  },

  render() {
    var {mapStyle, viewport} = this.state;
    return <MapGL
      onChangeViewport={this._onChangeViewport}
      mapStyle={mapStyle}
      {...viewport}
    />;
  }
});

module.exports = InteractiveMap;