Brian
Brian

Reputation: 1808

Dynamically add, update, delete markers in react-google-maps

Looking at the docs about react-google-maps, I was able to hack together some code to render a map with static data. Now I need to make changes to the map based on new data coming in from API or periodic updates and don't see any talk about how to do this.

To make the initial application, I did an "npx create-react-app xxx" to create an app and then added the necessary npm packages for react-google-maps. Here's basic code:

import React from 'react';
import ReactDOM from 'react-dom';
import './index.css';
import * as serviceWorker from './serviceWorker';
import { withScriptjs, withGoogleMap, GoogleMap, Marker } from "react-google-maps"


let markers = []

function createMarkers(numMarkers){

    for(let i = 0; i < numMarkers; i++){
        markers.push(<Marker key={i} position={{ lat: 45.123 + (i * 0.005), lng: -75.987 }} />)
    }

    return markers;
}

setInterval(function(){ 
  if(markers.length > 0 && markers[0].props.position){
    let marker = markers[0];
    //debugger;
    let position = marker.props.position;
    position.lat = position.lat - 0.005;
    position.lng = position.lng - 0.005;
    marker.props.position = position;
  }
}, 1000)

const MyGreatMap = withScriptjs( withGoogleMap(props => <GoogleMap
      defaultZoom={14}
      defaultCenter={{ lat: 45.123, lng: -75.978 }}
    >
      {createMarkers(10)}
    </GoogleMap>));


ReactDOM.render(
  <MyGreatMap 
    googleMapURL="https://maps.googleapis.com/maps/api/js?v=3.exp&libraries=geometry,drawing,places&key=AIzaSyDS-TFZqRfUx9xPXTJrPH6eml-gGo-btZ0"
    loadingElement={<div style={{ height: `100%` }} />}
    containerElement={<div style={{ height: `800px` }} />}
    mapElement={<div style={{ height: `100%` }} />}
  />, 
  document.getElementById('root'));

When I update the props, nothing happens. I'm sure that's wrong and it should be updating state somehow, but the lat/lng info in the markers are props.

What is the best way to update things in react-google-maps? Google maps in general is a very javascript intensive API so I don't know if it can work "the react way". What's the best way to make changes to react-google-maps to get them to efficiently re-render with changes?

Upvotes: 4

Views: 8544

Answers (1)

Vadim Gremyachev
Vadim Gremyachev

Reputation: 59338

I'm sure that's wrong and it should be updating state somehow, but the lat/lng info in the markers are props.

that's right, markers needs to moved to local state, For that matter a component could be introduced which accepts markers props as initial state and then state updated like this:

class MapWithMarkers extends React.Component {
  constructor(props) {
    super(props);
    this.state= {markers: this.props.markers};   //1.initialize initial state from props
  }

  updateMarker() {
      this.setState(prevState => {
        const markers = [...prevState.markers];
        markers[index] = {lat: <val>, lng: <val>};
        return {markers};
     })
  }

  componentDidMount() {
    this.intervalId = setInterval(this.updateMarker.bind(this), 1000);
  }
  componentWillUnmount(){
    clearInterval(this.intervalId);
  }
  
  render() {
    return (
      <Map center={this.props.center} zoom={this.props.zoom} places={this.state.markers} />
    ); 
  }
}

Demo

Upvotes: 3

Related Questions