【发布时间】:2020-07-09 18:22:28
【问题描述】:
我是 React 新手,所以可能会问一个愚蠢的问题,但这让我感到困惑。作为学习的一部分,我正在构建一个三组件应用程序 - 一个父级 About 和两个子级(GoogleMap 和 MapMarkerDetails)。父母进行数据协调,一个孩子默认显示带有两个标记的谷歌地图,另一个孩子在点击时显示标记的详细信息。
我现在正在添加功能以在单击地图时添加新标记。大多数功能都有效 - 绘制地图,添加默认标记,当单击其中一个标记时,这会调用父类上的一个函数来更新其状态,并将其传播到 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 地图和标记的类:
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 向下传递的(下面的sn-p)。在About 的addMarker 函数中,传入了lat/lng。这表示用户单击的位置。这将转换为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
}
发生了一些事情,导致GoogleMap 的render() 函数被调用,但只显示了原始标记。数据被传递到GoogleMap 组件,因为我可以看到console.log('render: ' + this.props.markers) 的输出。但是如何让所有标记加载?
请告知About 将数据传递给GoogleMap 以便添加新标记的最佳方法。
【问题讨论】:
标签: javascript reactjs google-maps