ReactJS和Google地图-显示标记

问题描述 投票:0回答:1

我是React新手,所以也许问一个愚蠢的问题,但这使我感到困惑。作为学习的一部分,我将构建一个包含三个部分的应用程序-父级About和两个子级[GoogleMapMapMarkerDetails)。父级进行数据协调,一个孩子显示带有两个标记的google map作为默认地图,另一个孩子在单击时显示标记的详细信息。

现在,我添加了单击地图时添加新标记的功能。大多数功能均可正常工作-绘制地图,添加默认标记,然后单击其中一个标记,这会在父类上调用一个函数,该函数会更新其状态并将其传播到MapMarkerDetails元素和显示简单消息。

这里是我评论过的以帮助理解的父类:

import React, { Component } from 'react';
import GoogleMap from './GoogleMap'
import MapMarkerDetails from './MapMarkerDetails'

class About extends Component {

state = {
    markers: [{
        position: { lat: 51.438759, lng: -2.864514 },
        label: 'A',
        map: null,
    }, {
        position: { lat: 51.433636, lng: -2.868734 },
        label: 'B',
        map: null,
    }],
    greeting: 'HelloA'
}

showMarkerInfo = (label) => {
    this.setState({greeting: ('Hello ' + label)})
}

/* 
Adding a new Marker 
This function is called from the child element GoogleMap
However, the setState(...) dosn't seem to propogate down to the GoogleMap element.
*/
addMarker = (latlng) => {
    let newMarker = [{
        position: { lat: latlng.lat(), lng: latlng.lng() },
        label: 'New',
        map: null,
    }];

    /* Creates a new array for updating state. Is this the best way to do this */
    let markers = [...this.state.markers, ...newMarker] 
    this.setState({markers});

    console.log(this.state) // This shows the added marker
}

render() {
    return (
        <div className="container">
            <h4 className="center">About</h4>
            <MapMarkerDetails details={this.state.greeting}/>
            <GoogleMap markers={this.state.markers} clickedMarker={this.showMarkerInfo} addMarker={this.addMarker}/>
        </div>
    )
    }
}

export default About;

这里是显示Google Map和标记的类:

import React, { Component } from 'react';

class GoogleMap extends Component {
  constructor(props) {
    super(props);
    this.googleMapRef = React.createRef(); // Create a referance for Google Map to draw to
    console.log('Constructore')
  }

  componentDidMount(){
    console.log('componentDidMount')
    /* Create the Map */
    let googleMap = new window.google.maps.Map(this.googleMapRef.current, {
      zoom: 15,
      center: {
        lat: 51.436411,
        lng: -2.861980,
      },
      disableDefaultUI: true,
    })

    this.placeMMarkers(googleMap) // Place the markers
    this.addMapListner(googleMap) // Define a click listener to place new markers
  }

  /* Place the markers */
  placeMMarkers = (googleMap) => {
    this.props.markers.forEach((m) => {
      m.map = googleMap;
       let marker= new window.google.maps.Marker(m)
       marker.addListener('click', () => { this.props.clickedMarker(m.label); });
     }
   );
 }

 /* Map listeners */
  addMapListner = (googleMap) => {
    googleMap.addListener('click', (e) => {
      this.props.addMarker(e.latLng)
    })
  }

  render() {
    console.log('render: ' + this.props.markers) // This is showing the added markers
    return (
      <div
        id="google-map"
        ref={this.googleMapRef}
        style={{ width: '800px', height: '400px', float: 'left' }}>
      </div>
    )
  }
}

export default GoogleMap

我已将控制台日志记录添加到每个功能,因此我可以跟踪发生的情况。

这里是MapMarkerDetails,当单击标记时,它会显示一条简单消息。这一切都很好。

import React, { Component } from 'react';

class MapMarkerDetails extends Component {

    render(){
        return (
            <div style={{width: '100px', height: '400px', backgroundColor: 'gray', float: 'left'}}>
                {this.props.details}
            </div>
        )
    }
}

export default MapMarkerDetails

问题描述

[当用户单击地图(而不是标记)时,它将调用从父addMarker类(下面的代码段)向下传递的函数About。在addMarkerAbout功能中,输入经纬度。这表示用户单击的位置。将其转换为marker数据对象,然后创建一个新数组,其中包含默认标记和新标记。我不确定我的新数组创建是否以最佳方式完成-如果没有让我知道。

一旦创建了新数组,我们将使用this.setState({markers})更新组件状态。我认为这将导致重新render()并使用添加的标记重新绘制地图。但不是。

addMarker = (latlng) => {
    let newMarker = [{
        position: { lat: latlng.lat(), lng: latlng.lng() },
        label: 'New',
        map: null,
    }];

    /* Creates a new array for updating state. Is this the best way to do this */
    let markers = [...this.state.markers, ...newMarker] 
    this.setState({markers});

    console.log(this.state) // This shows the added marker
}

发生某种情况,导致调用了render()GoogleMap函数,但是只显示了原始标记。数据向下传递到GoogleMap组件,因为我可以看到console.log('render: ' + this.props.markers)的输出。但是如何获取所有标记?

[请告知About将数据传递到GoogleMap以便可以添加新标记的最佳方法是什么。

javascript reactjs google-maps
1个回答
0
投票

就像在首次加载地图时使用componentDidMount强制添加标记一样,在更改道具时,也应使用componentDidUpdate做相同的事情。在您的GoogleMap组件中:

componentDidUpdate() {
  this.placeMMarkers(googleMap) // Place the markers
}

由于在placeMMarkers中附加了事件处理程序,因此还应该添加一些逻辑以区分新标记和现有标记,以避免将多个事件处理程序添加到现有标记。

© www.soinside.com 2019 - 2024. All rights reserved.