Ваш useEffect
хук выполняется только один раз. Вы получите это сообщение, скорее всего, из-за горячей перезагрузки и повторного подключения компонента Map
.
Чтобы избежать этого, просто используйте свойство окна, которое вы устанавливаете window.initMap
, чтобы проверить, являются ли сценарии карты загружено:
const createScriptLoadMap = () => {
if (!window.initMap) {
var index = window.document.getElementsByTagName("script")[0];
var script = window.document.createElement("script");
script.src =
"https://maps.googleapis.com/maps/api/js?key=AIzaSyDurZQBXjtSzKeieXwtFeGe-jhZu-HEGQU&libraries=drawing&callback=initMap";
script.async = true;
script.defer = true;
index.parentNode.insertBefore(script, index);
window.initMap = true;
}
};
РЕДАКТИРОВАТЬ
Что касается центрирования карты после извлечения некоторых данных, вам также следует go с крючками и useEffect
в уже есть mapCenter
объект состояния. Сначала используйте script.load
, чтобы увидеть, когда скрипт загружен. Вызовите initMap
независимо от того, загружен скрипт или нет, чтобы получить объект google.maps.Map
и сохраните его, используя состояние для последующего использования, иначе, если скрипт уже был загружен, просто назначьте объект карты:
const createScriptLoadMap = () => {
if (!window.initMap) {
var index = window.document.getElementsByTagName("script")[0];
var script = window.document.createElement("script");
script.src =
"https://maps.googleapis.com/maps/api/js?key=AIzaSyDurZQBXjtSzKeieXwtFeGe-jhZu-HEGQU&libraries=drawing&callback=initMap";
script.async = true;
script.defer = true;
script.onload = () => {
initMap();
};
index.parentNode.insertBefore(script, index);
window.initMap = true;
} else {
initMap();
}
};
Затем измените initMap
функция для инициализации или присвоения объекта google.maps.Map
для элемента DOM #map
(, который не будет создавать новую карту, если мы уже присвоили элемент ранее ):
const initMap = () => {
let googleMap = new google.maps.Map(document.getElementById("map"), {
center: { lat: 37.978534, lng: 23.743830 }, //CURRENTLY STATIC
//center: {mapCenter} //ACTUAL
zoom: 14
});
// Save the map object created for later usage
setMap(googleMap);
// axios.get(`${BASE_URL_LOCAL}/outlet/list?page=1&limit=50`).then(res => {
// let center = averageGeolocation(res.data.data.outlets);
// console.log(props.mapCenter);
// setFetchedData(res);
// setMapCenter(center) //THIS CENTER IS REQUIRED IN LINE 22
// });
// Suppose get an Axios response after 2 seconds
setTimeout(() => {
// Center map at NY Brooklyn using state (effect for mapCenter will be triggered)
setMapCenter({ lat: 40.674282, lng: -73.943060 });
}, 2000);
};
Это создаст объект google.aps.Map
и сохранит его в состоянии setMap
для последующего использования. Теперь, когда вы хотите обновить центр карты ( или любые другие свойства / методы карты ), просто установите useEffect
hook на mapCenter
объект состояния и затем используйте объект map
для изменения Карта:
const [mapCenter, setMapCenter] = useState({});
const [fetchedData, setFetchedData] = useState({});
const [map, setMap] = useState();
useEffect(() => {
createScriptLoadMap();
}, []);
useEffect(() => {
if(map) {
map.setCenter(mapCenter)
}
}, [mapCenter]);
Проверьте мои раздвоенные и обновленные stackblitz
. Вы увидите, что карта начинается из Афин и через 2 секунды ( предположим, что у нас есть асинхронный топор ios call ), она центрирует карту в Нью-Йорк Бруклин. ( Я создал ключ API Карт Google для демонстрации, я удалю после вашего ответа ).