import React from 'react'
import PropTypes from 'prop-types'
import { Map, TileLayer, GeoJSON } from 'react-leaflet'

import 'leaflet/dist/leaflet.css'

// Fix icon issues when importing images with webpack
// https://github.com/PaulLeCam/react-leaflet/issues/255
import L from 'leaflet'
delete L.Icon.Default.prototype._getIconUrl

L.Icon.Default.mergeOptions({
  iconRetinaUrl: require('leaflet/dist/images/marker-icon-2x.png'),
  iconUrl: require('leaflet/dist/images/marker-icon.png'),
  shadowUrl: require('leaflet/dist/images/marker-shadow.png')
})

class CenteredMap extends React.PureComponent {
  static propTypes = {
    vectors: PropTypes.object.isRequired,
    className: PropTypes.string,
    frozen: PropTypes.bool,

    lat: PropTypes.number,
    lon: PropTypes.number,
    zoom: PropTypes.number
  }

  static defaultProps = {
    frozen: false,
    lat: 47,
    lon: 1,
    zoom: 4
  }

  componentDidMount() {
    if (this.vectors) {
      this.setState({
        bounds: this.vectors.leafletElement.getBounds()
      })
    }
  }

  render() {
    const { vectors, className, frozen, lat, lon, zoom } = this.props
    const { bounds } = this.state

    return (
      <Map
        className={className}
        center={[lat, lon]}
        bounds={bounds}
        minZoom={zoom}
        dragging={!frozen}
        scrollWheelZoom={false}
        doubleClickZoom={!frozen}
        zoomControl={!frozen}
      >
        <TileLayer
          attribution='© Contributeurs <a href="http://osm.org/copyright">OpenStreetMap</a>'
          url='https://{s}.tile.openstreetmap.fr/osmfr/{z}/{x}/{y}.png'
        />

        <GeoJSON
          color='blue'
          fillOpacity={0.1}
          weight={2}
          ref={vectors => {
            this.vectors = vectors
          }}
          data={vectors}
        />
      </Map>
    )
  }
}

export default CenteredMap

@@ -265,16 +265,22 @@
 import L
+eaflet
  from 'l
@@ -295,16 +295,22 @@
 delete L
+eaflet
 .Icon.De
@@ -339,16 +339,22 @@
 onUrl%0A%0AL
+eaflet
 .Icon.De
@@ -603,12 +603,8 @@
 act.
-Pure
 Comp
@@ -926,11 +926,12 @@
 nent
-Did
+Will
 Moun
@@ -944,120 +944,518 @@
     
-if (this.vectors) %7B%0A      this.setState(%7B%0A        bounds: this.vectors.leafletElement.getBounds()%0A      %7D)%0A    %7D
+// We%E2%80%99re computing bounds only once: when the component will mount.%0A    // Whatever happens, GeoJSON will not re-render if the input data changes.%0A    // So we%E2%80%99re safe only computing once.%0A    this.bounds = Leaflet.geoJson(this.props.vectors).getBounds()%0A  %7D%0A%0A  shouldComponentUpdate() %7B%0A    // As seen in componentWillMount, we do not need to re-render this component.%0A    // All the props are not going to change.%0A    // If we ever need this to re-render on prop changes, remove this method.%0A    return false
 %0A  %7D
@@ -1542,42 +1542,8 @@
 rops
-%0A    const %7B bounds %7D = this.state
 %0A%0A  
@@ -1638,16 +1638,21 @@
 bounds=%7B
+this.
 bounds%7D%0A
@@ -2094,84 +2094,8 @@
 %7B2%7D%0A
-          ref=%7Bvectors =%3E %7B%0A            this.vectors = vectors%0A          %7D%7D%0A
     

Fix and optimize the way leaflet bounds are computed