-->

How to add map markers stored in a JSON feed to an

2019-05-30 05:59发布

问题:

I have a react-google-maps project which creates a map:

const MarkerComponent = ({text}) => <div>{text}</div>;

export default class NavMap extends Component {
  constructor(props) {
    super(props);
    this.state = {
      markers: []
    }
  }

  static defaultProps = {
    center: {lat: -41.25,lng: 173.2},
    zoom: 11
  }
  render() {
    return (<div id="nav-map" className='google-map'>
    <GoogleMapReact 
      name={map} 
      apiKey={'MYAPIKEY'} 
      defaultCenter={this.props.center} 
      defaultZoom={this.props.zoom}>
      <MarkerComponent lat={-41.25} lng={173.2} text={'Centre'}/>
    </GoogleMapReact>
    </div>)
  }
}

This will add a text marker to the centre of the map.

However I can't work how to add the markers from a dynamic JSON feed that is loaded after the map is created/ loaded in React. Please note the JSON feed could be updated - at which point the markers would be refreshed.

In React I normally call a JSON feed like this:

componentDidMount() {
  fetch('/myJSONfeed').then(response => response.json()).then(data => {
    this.setState({data});
  });
 }

I've had a good look around online for a solution but have not being able to work out how to add dynamic markers after the map has been created/ loaded.

Any ideas or example code would be appreciated.

回答1:

I have encountered the same issue recently. Hope this explanation will help you to figure out what went wrong.

Overview

When we are working with external sources. It's important to note that nothing guarantees you the order of tasks to be executed. As in your case, fetching a JSON feed is fetched asynchronously.

The problem

Fetching the feed inside componentDidMount() should be fine. However, you still need to wait for the data to available. Hence, you should tell others components to listen for that event, and update their properties thereafter.

The Solution

By using the componentDidMount() we can wait for the map to load, and properties to propagate into the components. Then, with componentDidUpdate() we can operate on the DOM.

It goes like this:

In App.js:

    componentDidMount(){
        fetch(THE_SOURCE_TO_BE_FETCHED)
        .then(function(response) {
            return response.json();
        }).then(data => {
            this.setState({markers: data});
        });
    }

In the Map component

    componentDidUpdate(){
        const google = window.google;

        this.map = new google.maps.Map(this.refs.map, {
            center: this.props.center,
            zoom: 4
        });

        this.createMarkers(this.props.markers)
    }

    createMarkers(users){
        const google = window.google;

        users.map(user => {
            this.marker = new google.maps.Marker({
                position: {
                    lat: user.location.latitude,
                    lng: user.location.longitude
                },
                map: this.map,
            });
            this.state.markers.push(this.marker);
        })
    }

Please note: you should carefully examine your JSON and check that it is valid, as well as if it subject to be parsed from string etc.

Take a tour at React's docs of React's component lifecycle if you need more details.

GL & HF