在使用功能组件时,如何在用户单击标记时显示信息窗口?
How do I make an infowindow appear when the user clicks the marker, while using a functional component?
我为此使用的 Google 地图 API 库是 https://github.com/JustFly1984/react-google-maps-api
我被要求创建的是一个带有多个标记的地图,单击每个标记都可以打开以该标记为中心的信息窗口。很像 AirBnB 的搜索页面,地图在一侧,结果在另一侧。
不过,我好像只能有一个在加载页面时打开的InfoWindow,然后就不能再打开了。
到目前为止,我的研究大体表明我需要将此组件完全重做为 class。虽然我不太了解基于 class 的组件模型,但理想情况下我不必乱搞它。
有没有一种方法可以在不完全修改我的程序的情况下达到预期的效果?
这是组件的代码,以防相关
import styles from '../../styles/Home.module.css';
import { Marker, LoadScriptNext, GoogleMap, InfoWindow } from '@react-google-maps/api';
import { Fragment, React } from 'react';
import { Typography } from '@material-ui/core';
export default function MapPanel(props) {
return (
<Fragment>
<LoadScriptNext id='google-map-example' googleMapsApiKey="MYAPIKEY">
<GoogleMap mapContainerStyle={{ width: "100%", height: "800px" }}
id='google-map'
center={props.centre}
heading="0"
zoom={12}>
{addMarkers(props.markerList)}
</GoogleMap>
</LoadScriptNext>
</Fragment>
);
}
function addMarkers(markerList) {
if (markerList != undefined) {
return (markerList.map((marker, index) => makeMarker(marker, index)))
}
}
function makeMarker(marker, index) {
const handleClick = () => {
console.log(`${marker.title} marker clicked`);
}
return (
<Marker id={index} position={marker.latLong} title={marker.title} onClick={handleClick}>
<InfoWindow id='Test' position={marker.latLong}>
<Typography variant='body2'>{marker.text}</Typography>
</InfoWindow>
</Marker>
);
}
为了实现您的目标,您可能希望在应用程序中使用状态。但是既然你想用函数组件来处理它,你就需要利用react hooks来使用状态。
这里有一个工作示例供您参考:https://stackblitz.com/edit/marker-with-infowindow-react-api-o6357y
import ReactDOM from "react-dom";
import React from "react";
import {
GoogleMap,
Marker,
InfoWindow,
LoadScript
} from "@react-google-maps/api";
import data from "./data.json";
const { useState } = React;
const containerStyle = {
width: "400px",
height: "400px"
};
const center = { lat: 40.712775, lng: -74.005973 };
function Map() {
const [infoWindowID, setInfoWindowID] = useState("");
let markers;
if (data !== null) {
markers = data.map((location, i) => {
const marker = { lat: location.lat, lng: location.lng };
const index = i + 1;
return (
<Marker
key={index}
position={marker}
label={index.toString()}
onClick={() => {
setInfoWindowID(index);
}}
>
{infoWindowID === index && (
<InfoWindow>
<span>Something {index}</span>
</InfoWindow>
)}
</Marker>
);
});
}
return (
<LoadScript googleMapsApiKey="YOUR_API_KEY">
<GoogleMap mapContainerStyle={containerStyle} center={center} zoom={10}>
{markers}
</GoogleMap>
</LoadScript>
);
}
export default React.memo(Map);
我为此使用的 Google 地图 API 库是 https://github.com/JustFly1984/react-google-maps-api
我被要求创建的是一个带有多个标记的地图,单击每个标记都可以打开以该标记为中心的信息窗口。很像 AirBnB 的搜索页面,地图在一侧,结果在另一侧。
不过,我好像只能有一个在加载页面时打开的InfoWindow,然后就不能再打开了。
到目前为止,我的研究大体表明我需要将此组件完全重做为 class。虽然我不太了解基于 class 的组件模型,但理想情况下我不必乱搞它。
有没有一种方法可以在不完全修改我的程序的情况下达到预期的效果?
这是组件的代码,以防相关
import styles from '../../styles/Home.module.css';
import { Marker, LoadScriptNext, GoogleMap, InfoWindow } from '@react-google-maps/api';
import { Fragment, React } from 'react';
import { Typography } from '@material-ui/core';
export default function MapPanel(props) {
return (
<Fragment>
<LoadScriptNext id='google-map-example' googleMapsApiKey="MYAPIKEY">
<GoogleMap mapContainerStyle={{ width: "100%", height: "800px" }}
id='google-map'
center={props.centre}
heading="0"
zoom={12}>
{addMarkers(props.markerList)}
</GoogleMap>
</LoadScriptNext>
</Fragment>
);
}
function addMarkers(markerList) {
if (markerList != undefined) {
return (markerList.map((marker, index) => makeMarker(marker, index)))
}
}
function makeMarker(marker, index) {
const handleClick = () => {
console.log(`${marker.title} marker clicked`);
}
return (
<Marker id={index} position={marker.latLong} title={marker.title} onClick={handleClick}>
<InfoWindow id='Test' position={marker.latLong}>
<Typography variant='body2'>{marker.text}</Typography>
</InfoWindow>
</Marker>
);
}
为了实现您的目标,您可能希望在应用程序中使用状态。但是既然你想用函数组件来处理它,你就需要利用react hooks来使用状态。
这里有一个工作示例供您参考:https://stackblitz.com/edit/marker-with-infowindow-react-api-o6357y
import ReactDOM from "react-dom";
import React from "react";
import {
GoogleMap,
Marker,
InfoWindow,
LoadScript
} from "@react-google-maps/api";
import data from "./data.json";
const { useState } = React;
const containerStyle = {
width: "400px",
height: "400px"
};
const center = { lat: 40.712775, lng: -74.005973 };
function Map() {
const [infoWindowID, setInfoWindowID] = useState("");
let markers;
if (data !== null) {
markers = data.map((location, i) => {
const marker = { lat: location.lat, lng: location.lng };
const index = i + 1;
return (
<Marker
key={index}
position={marker}
label={index.toString()}
onClick={() => {
setInfoWindowID(index);
}}
>
{infoWindowID === index && (
<InfoWindow>
<span>Something {index}</span>
</InfoWindow>
)}
</Marker>
);
});
}
return (
<LoadScript googleMapsApiKey="YOUR_API_KEY">
<GoogleMap mapContainerStyle={containerStyle} center={center} zoom={10}>
{markers}
</GoogleMap>
</LoadScript>
);
}
export default React.memo(Map);