在组件中呈现时标记的错误位置
Wrong location of marker when rendered in component
我正在尝试使用 ReactJs 在 Google 地图上显示一些标记。
现在我有两个固定位置(伦敦和巴黎),但稍后我想从服务器加载位置,所以我希望它们在单独的组件中处理。
出于某种原因,当我在单独的组件中渲染巴黎时,它被放到了地图的一角。我可以四处移动地图,缩放它,但巴黎仍然在角落里。
这是我的代码:
var center = { lat: 49.1951, lng: 16.6068 };
var zoom = 3;
const K_WIDTH = 40;
const K_HEIGHT = 40;
const greatPlaceStyle = {
// initially any map object has left top corner at lat lng coordinates
// it's on you to set object origin to 0,0 coordinates
position: 'absolute',
width: K_WIDTH,
height: K_HEIGHT,
left: -K_WIDTH / 2,
top: -K_HEIGHT / 2,
border: '5px solid #f44336',
borderRadius: K_HEIGHT,
backgroundColor: 'white',
textAlign: 'center',
color: '#3f51b5',
fontSize: 16,
fontWeight: 'bold',
padding: 4
};
class PlaceMarkers extends React.Component{
render(){
return(
<div style={greatPlaceStyle} lat="48.8566" lng="2.3522">Paris</div>
)
}
}
class PlaceBlock extends React.Component{
render(){
return(
<div>
<div className="thumbnail ep-map">
<GoogleMap defaultCenter={center} defaultZoom={zoom}>
<div style={greatPlaceStyle} lat="51.5074" lng="0.1278">London</div>
<PlaceMarkers/>
</GoogleMap>
</div>
</div>
)
}
我对 ReactJs 很陌生,所以它可能很简单?
编辑:
感谢 Max 我做了一些修改。现在,即使从服务器加载(使用 axios 进行 GET),我的标记也能正常工作。我没有将每个标记作为单独的组件,而是将我的组件重命名为 GoogleMapBlock 并让它处理包括标记的地图:
class GoogleMapBlock extends React.Component{
constructor(props) {
super(props);
this.state = {
markers: []
};
}
componentDidMount() {
axios
.get(getBaseUrl()+`get`)
.then((response) => {
this.setState({
markers: response.data.markers
});
})
.catch((e) =>
{
console.error(e);
});
}
render(){
var myMarkers = [];
var count = 1;
this.state.markers.forEach(function(marker){
var markerId = "markerId" + count;//marker.key
myMarkers.push(
<div id={markerId} style={greatPlaceStyle} lat={marker.position.lat} lng={marker.position.lng}>{marker.title}</div>
);
count++;
});
return(
<div className="thumbnail ep-map">
<GoogleMap defaultCenter={center} defaultZoom={zoom}>
{myMarkers}
</GoogleMap>
</div>
);
}
}
发生这种情况是因为 GoogleMap 组件需要在其子组件下使用 lat 和 lng 道具。如果你查看 React 开发工具,你会看到 google 映射下有 2 个组件:
- div 经纬度
- 没有 lat 和 lng 的 PlaceMarkers(有 div 有 lat 和 lng)
您需要明确地为 PlaceMarkers 设置 lat 和 lng 属性:
<GoogleMap defaultCenter={center} defaultZoom={zoom}>
<div style={greatPlaceStyle} lat="51.5074" lng="0.1278">London</div>
<PlaceMarkers lat="48.8566" lng="2.3522"/>
</GoogleMap>
React Component 是一个视图,因此它不应该被用来存储数据(尽管它可能仍然有视图状态),这就是我们需要 props 的原因——用数据初始化组件。在你的情况下,我建议选择一个存储框架,比如 Redux,并在运行时初始化组件:
render() {
let markers = this.state.markers.map(m => <PlaceMarkers {...m}/>);
return <GoogleMap defaultCenter={center} defaultZoom={zoom}>
{markers}
</GoogleMap>
}
,其中 this.state.markers 是数组,如 [{lat: "48.8566", lng: "2.3522", name: "London"}, ...]
我正在尝试使用 ReactJs 在 Google 地图上显示一些标记。
现在我有两个固定位置(伦敦和巴黎),但稍后我想从服务器加载位置,所以我希望它们在单独的组件中处理。
出于某种原因,当我在单独的组件中渲染巴黎时,它被放到了地图的一角。我可以四处移动地图,缩放它,但巴黎仍然在角落里。
这是我的代码:
var center = { lat: 49.1951, lng: 16.6068 };
var zoom = 3;
const K_WIDTH = 40;
const K_HEIGHT = 40;
const greatPlaceStyle = {
// initially any map object has left top corner at lat lng coordinates
// it's on you to set object origin to 0,0 coordinates
position: 'absolute',
width: K_WIDTH,
height: K_HEIGHT,
left: -K_WIDTH / 2,
top: -K_HEIGHT / 2,
border: '5px solid #f44336',
borderRadius: K_HEIGHT,
backgroundColor: 'white',
textAlign: 'center',
color: '#3f51b5',
fontSize: 16,
fontWeight: 'bold',
padding: 4
};
class PlaceMarkers extends React.Component{
render(){
return(
<div style={greatPlaceStyle} lat="48.8566" lng="2.3522">Paris</div>
)
}
}
class PlaceBlock extends React.Component{
render(){
return(
<div>
<div className="thumbnail ep-map">
<GoogleMap defaultCenter={center} defaultZoom={zoom}>
<div style={greatPlaceStyle} lat="51.5074" lng="0.1278">London</div>
<PlaceMarkers/>
</GoogleMap>
</div>
</div>
)
}
我对 ReactJs 很陌生,所以它可能很简单?
编辑:
感谢 Max 我做了一些修改。现在,即使从服务器加载(使用 axios 进行 GET),我的标记也能正常工作。我没有将每个标记作为单独的组件,而是将我的组件重命名为 GoogleMapBlock 并让它处理包括标记的地图:
class GoogleMapBlock extends React.Component{
constructor(props) {
super(props);
this.state = {
markers: []
};
}
componentDidMount() {
axios
.get(getBaseUrl()+`get`)
.then((response) => {
this.setState({
markers: response.data.markers
});
})
.catch((e) =>
{
console.error(e);
});
}
render(){
var myMarkers = [];
var count = 1;
this.state.markers.forEach(function(marker){
var markerId = "markerId" + count;//marker.key
myMarkers.push(
<div id={markerId} style={greatPlaceStyle} lat={marker.position.lat} lng={marker.position.lng}>{marker.title}</div>
);
count++;
});
return(
<div className="thumbnail ep-map">
<GoogleMap defaultCenter={center} defaultZoom={zoom}>
{myMarkers}
</GoogleMap>
</div>
);
}
}
发生这种情况是因为 GoogleMap 组件需要在其子组件下使用 lat 和 lng 道具。如果你查看 React 开发工具,你会看到 google 映射下有 2 个组件: - div 经纬度 - 没有 lat 和 lng 的 PlaceMarkers(有 div 有 lat 和 lng)
您需要明确地为 PlaceMarkers 设置 lat 和 lng 属性:
<GoogleMap defaultCenter={center} defaultZoom={zoom}>
<div style={greatPlaceStyle} lat="51.5074" lng="0.1278">London</div>
<PlaceMarkers lat="48.8566" lng="2.3522"/>
</GoogleMap>
React Component 是一个视图,因此它不应该被用来存储数据(尽管它可能仍然有视图状态),这就是我们需要 props 的原因——用数据初始化组件。在你的情况下,我建议选择一个存储框架,比如 Redux,并在运行时初始化组件:
render() {
let markers = this.state.markers.map(m => <PlaceMarkers {...m}/>);
return <GoogleMap defaultCenter={center} defaultZoom={zoom}>
{markers}
</GoogleMap>
}
,其中 this.state.markers 是数组,如 [{lat: "48.8566", lng: "2.3522", name: "London"}, ...]