30
loading...
This website collects cookies to deliver better user experience
<script src="https://unpkg.com/react@16/umd/react.development.js" crossorigin></script>
<script src="https://unpkg.com/react-dom@16/umd/react-dom.development.js" crossorigin></script>
SimpleHereMap
. The componentDidMount()
method runs after the render()
method per the React Component Lifecycle which means we can more or less include the HERE JavaScript Quick Start code just as is.const e = React.createElement;
class SimpleHereMap extends React.Component {
componentDidMount() {
var platform = new H.service.Platform({
app_id: 'APP_ID_HERE',
app_code: 'APP_CODE_HERE',
})
var layers = platform.createDefaultLayers();
var map = new H.Map(
document.getElementById('map'),
layers.normal.map,
{
center: {lat: 42.345978, lng: -83.0405},
zoom: 12,
});
var events = new H.mapevents.MapEvents(map);
var behavior = new H.mapevents.Behavior(events);
var ui = H.ui.UI.createDefault(map, layers);
}
render() {
return e('div', {"id": "map"});
}
}
const domContainer = document.querySelector('#app');
ReactDOM.render(e(SimpleHereMap), domContainer);
create-react-app
. If you use that tool as described in a few of the other ReactJS posts you may see the next error.create-react-app
requires a few minor changes.render()
method to use JSX to place the element.npm start
you will likely see the following error in your console:H.service.Platform()
is causing an error because H is not in scope. This is not unique to HERE and is generally the case with any 3rd party code you try to include with React. Using create-react-app
implies using its toolchain including webpack as a module bundler, eslint for checking syntax, and Babel to transpile JSX.window.H
instead. Unfortunately, this does violate one of the basic principles of building modular JavaScript applications by tightly coupling our <script>
includes with our component but it works.@@ -4,6 +4,14 @@
<meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">
+
+ <link rel="stylesheet" type="text/css" href="https://js.api.here.com/v3/3.0/mapsjs-ui.css?dp-version=1526040296" />
+
+ <script type="text/javascript" src="https://js.api.here.com/v3/3.0/mapsjs-core.js"></script>
+ <script type="text/javascript" src="https://js.api.here.com/v3/3.0/mapsjs-service.js"></script>
+ <script type="text/javascript" src="https://js.api.here.com/v3/3.0/mapsjs-ui.js"></script>
+ <script type="text/javascript" src="https://js.api.here.com/v3/3.0/mapsjs-mapevents.js"></script>
+
class Map extends Component {
constructor(props) {
super(props);
this.platform = null;
this.map = null;
this.state = {
app_id: props.app_id,
app_code: props.app_code,
center: {
lat: props.lat,
lng: props.lng,
},
zoom: props.zoom,
theme: props.theme,
style: props.style,
}
}
// TODO: Add theme selection discussed later HERE
componentDidMount() {
this.platform = new window.H.service.Platform(this.state);
var layer = this.platform.createDefaultLayers();
var container = document.getElementById('here-map');
this.map = new window.H.Map(container, layer.normal.map, {
center: this.state.center,
zoom: this.state.zoom,
})
var events = new window.H.mapevents.MapEvents(this.map);
// eslint-disable-next-line
var behavior = new window.H.mapevents.Behavior(events);
// eslint-disable-next-line
var ui = new window.H.ui.UI.createDefault(this.map, layer)
}
render() {
return (
<div id="here-map" style={{width: '100%', height: '400px', background: 'grey' }} />
);
}
}
class ThemeSelector extends Component {
render() {
var themes = [
'normal.day',
'normal.day.grey',
'normal.day.transit',
'normal.night',
'normal.night.grey',
'reduced.night',
'reduced.day',
'pedestrian.day',
'pedestrian.night',
];
var thumbnails = [];
var onChange = this.props.changeTheme;
themes.forEach(function(theme) {
thumbnails.push(<img key={ theme } src={ 'images/' + theme + '.thumb.png' } onClick= { onChange } alt={ theme } id={ theme } />);
});
return (
<div>
{ thumbnails }
</div>
);
}
}
changeTheme
method described below is an example like you’d find for most any HERE JavaScript implementation.changeTheme(theme, style) {
var tiles = this.platform.getMapTileService({'type': 'base'});
var layer = tiles.createTileLayer(
'maptile',
theme,
256,
'png',
{'style': style}
);
this.map.setBaseLayer(layer);
}
shouldComponentUpdate()
method. From the React Component Lifecycle, this method is called when state changes occur in order to determine if it’s necessary to re-render the component. When we select a new theme, we call the setBaseLayer
method and can update the map without requiring React to make a more costly re-render of the entire DOM.shouldComponentUpdate(props, state) {
this.changeTheme(props.theme, props.style);
return false;
}
import Map from './Map.js';
import ThemeSelector from './ThemeSelector.js';
class App extends Component {
constructor(props) {
super(props);
this.state = {
theme: 'normal.day',
}
this.onChange = this.onChange.bind(this);
}
onChange(evt) {
evt.preventDefault();
var change = evt.target.id;
this.setState({
"theme": change,
});
}
render() {
return (
<div className="App">
<SimpleHereMap
app_id="APP_ID_HERE"
app_code="APP_CODE_HERE"
lat="42.345978"
lng="-83.0405"
zoom="12"
theme={ this.state.theme }
/>
<ThemeSelector changeTheme={ this.onChange } />
</div>
);
}
}
npm
package that encapsulates the HERE Map APIs as React components for use in our applications. There are some community projects to create these packages but your experience may vary depending on which one you choose to use. It would be good to know what you’ve used successfully, so leave a note in the comments.