Jacob Stoebel

Using react leaflet

For my new nightlife app I am using leaflet.js to handle marking search results on a map. Leaflet was an immediate win for this project because so much comes, basically for free right out of the box: you get beautiful looking maps, markers, and pop ups with hardly anything to configure. What could be better? Oh I know, how about wrapping this functionality in React components! That way I can render a series of markers on a map with something like:

<Map bounds={this.state.corners}>
  <TileLayer
    url='http://{s}.tile.osm.org/{z}/{x}/{y}.png'
    attribution='&copy; <a href="http://osm.org/copyright">OpenStreetMap</a> contributors'
  />
  {this.props.results.map(this._eachBar)}
</Map>

Neato! There are a few gotchas with react-leaflet though. At its core, leaflet is not using React, and instead manipulates the DOM on its own. This creates some interesting, unexpected results. For example when a popup is rendered, its doesn't go where you expect it to go in the virtual DOM:

<BrowserRouter></BrowserRouter>
<div>
    <h5> Burgers and Brew </h5>
    </rsvpButton>
</div>

Doh! This means that the popup is completely outside the of the context and thus doesn't have access to the redux store. If you were hoping to mapStateToProps like normal, you're out of luck. Instead we have to pass props in the old fashioned way:

/* 
  Map.jsx
  map component. This function shows representation of a single bar which 
  contains a marker with popup. Since passing in state won't work, we just
  pass the props in directly. 
*/
_eachBar(bar, idx) {
  // render a single bar on the map
  //grab the cooridnates in strucutre leaflet requires
  const coords = [
    bar.coordinates.latitude,
    bar.coordinates.longitude
  ]
  return (
    <Marker position={coords} key={idx} >
      <Popup>
        <div>
          <h5>{bar.name}</h5>
          <RSVPButton 
            bar={bar} 
            currentRSVPs={this.props.currentRSVPs} 
            onFetchBars={this.props.onFetchBars}
            onAddError={this.props.onAddError}
          />
        </div>
      </Popup>
    </Marker>
  )
}

I've only begun to scratch the surface with what leaflet can do. Its not implemented with React so at its core you need to be a little flexible with your style, but in the end I think its worth working with.