Я использую Google Map API в своем приложении React (с помощью хуков).
Используется Google Places & Maps API. Пользователь может искать место, после выбора из выпадающего списка карта фокусируется на этом месте. Или пользователь может перетащить / увеличить карту, чтобы получить местоположение.
Код Объяснение:
В приведенном ниже коде, когда пользователь выбирает из выпадающего списка, я сохраняю ограниченную рамку (координаты NE и SW) в родительском компоненте (не показано здесь) состояние. Это вызывает обновление реквизита для этого компонента, который обновляет карту.
Следующий код работает нормально, пока я не добавляю прослушиватель для zoom-changed
, потому что прослушиватель для drag-end
и ввод для поиска не конфликтуют друг с другом. Однако я хочу добавить также функцию масштабирования, и это срабатывает при выборе поиска, и приложение переходит в бесконечное обновление.
Код:
const ModalGoogleMap = ({ locationSearch, saveLocationSearch, toggleMapModal }) => {
const defaultCenter = { lat: 51.509865, lng: -0.118092 }
const defaultZoom = 9;
const mapDimensions = { width: 900, height: 508 };
const [gMap, setGMap] = useState();
const { register } = useForm();
const searchInputRef = useRef();
let mapContainerRef = useRef();
const { address, boundBox } = locationSearch;
let getPlaces: any;
useEffect(() => {
initMap();
initSearchInput();
}, []);
useEffect(() => {
if (boundBox) {
const { sw, ne } = boundBox;
const latlng = new google.maps.LatLngBounds(sw, ne);
gMap.fitBounds(latlng, 0);
}
}, [boundBox]);
const initMap = () => {
const gMap = new google.maps.Map(
mapContainerRef.current,
{
zoom: defaultZoom,
center: defaultCenter
});
gMap.addListener("dragend", () => mapEvHandler(gMap));
// zoom-changed listener is triggered everytime a user searches & selects from search-input
gMap.addListener("zoom_changed", () => mapEvHandler(gMap));
setGMap(gMap);
};
const initSearchInput = () => {
const searchInput = new google.maps.places.SearchBox(searchInputRef.current);
searchInput.addListener('places_changed', () => {
getPlaces = searchInput.getPlaces();
const { formatted_address: address, geometry: { location, viewport } } = getPlaces[0];
const boundBox = calcNESW(viewport);
saveLocationSearch({
address,
boundBox,
center: { lat: location.lat(), lng: location.lng() },
zoom: 12,
});
});
};
const mapEvHandler = (gMap) => {
const mapBounds = gMap.getBounds();
const getCenter = gMap.getCenter();
const getZoom = gMap.getZoom();
const boundBox = calcNESW(mapBounds); // func returns NE & SW co-ords
saveLocationSearch({
address: `[${getCenter.lat()}, ${getCenter.lng()}]`,
boundBox,
zoom: getZoom,
center: getCenter
});
};
Как мне обновить logi c, чтобы не запускать обработчик zoom-changed
, если пользователь не запускает с помощью элементов управления масштабированием. Я чувствую, что упускаю важный аспект React Hooks useEffect
.