Skip to content

Instantly share code, notes, and snippets.

Embed
What would you like to do?
/* global mapboxgl */
import React, { Component } from 'react';
import { connect } from 'react-redux';
import { bindActionCreators } from 'redux';
import Immutable from 'immutable';
import { clickMap, setStyle } from '../actions/index';
import diffStyles from '../utilities/diff.js';
class ReactMap extends Component {
componentDidMount(){
// set map properties
const { token, longitude, latitude, zoom, styleID } = this.props;
const mapConfig = {
container: 'map',
style: `mapbox://styles/${ styleID }`,
center: [longitude, latitude],
zoom: zoom,
};
mapboxgl.accessToken = token;
this.map = new mapboxgl.Map(mapConfig);
this.map.on('load', () => {
// Get the map style and set it in the state tree
const style = this.map.getStyle();
this.props.setStyle(style);
this.map.on('click', event => {
const features = this.map.queryRenderedFeatures(event.point);
this.props.clickMap(features);
if(this.props.popupMarkup) {
new mapboxgl.Popup()
.setLngLat(event.lngLat)
.setHTML(this.props.popupMarkup)
.addTo(this.map);
}
});
});
}
// Utilizes diffStyles to update the DOM map from a new Immutable stylesheet
componentWillReceiveProps(nextProps) {
if(this.props.mapStyle === null) return;
const map = this.map;
const oldStyle = this.props.mapStyle;
const newStyle = nextProps.mapStyle;
if(!Immutable.is(oldStyle, newStyle)) {
const changes = diffStyles(oldStyle.toJS(), newStyle.toJS());
changes.forEach(change => {
map[change.command].apply(map, change.args);
});
}
}
render(){
return (
<div id='map'></div>
);
}
}
function mapDispatchToProps(dispatch) {
return bindActionCreators({
clickMap: clickMap,
setStyle: setStyle
}, dispatch);
}
function mapStateToProps(state) {
return {
mapStyle: state.mapStyle,
userInterface: state.userInterface
};
}
export default connect(mapStateToProps, mapDispatchToProps)(ReactMap);
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment