所以這段代碼是有效的,但有時在頁面加載或重繪 時,谷歌位置下拉自動完成建議沒有顯示,我可以在搜索框中輸入任何內容,但它只是不加載自動完成框。什么可能導致這個問題?
這是代碼。
const apiKey = process.env.REACT_APP_GOOGLE_KEY;
const mapApiJs = 'https://maps.googleapis.com/maps/api/js';
const geocodeJson = 'https://maps.googleapis.com/maps/api/geocode/json';
// load google map api js
function loadAsyncScript(src) {
return new Promise(resolve => {
const script = document.createElement("script");
Object.assign(script, {
type: "text/javascript",
async: true,
src
})
script.addEventListener("load", () => resolve(script));
document.head.appendChild(script);
})
}
const extractAddress = (place) => {
const address = {
city: "",
state: "",
zip: "",
country: "",
plain() {
const city = this.city ? this.city ", " : "";
const zip = this.zip ? this.zip ", " : "";
const state = this.state ? this.state ", " : "";
return city zip state this.country;
}
}
if (!Array.isArray(place?.address_components)) {
return address;
}
if(typeof place.geometry.location.lat === 'function') {
address.lat = place.geometry.location.lat();
} else {
address.lat = place.geometry.location.lat;
}
if(typeof place.geometry.location.lng === 'function') {
address.lng = place.geometry.location.lng();
} else {
address.lng = place.geometry.location.lng;
}
place.address_components.forEach(component => {
const types = component.types;
const value = component.long_name;
if (types.includes("locality")) {
address.city = value;
}
if (types.includes("administrative_area_level_2")) {
address.state = value;
}
if (types.includes("postal_code")) {
address.zip = value;
}
if (types.includes("country")) {
address.country = value;
}
});
return address;
}
function ReportForm() {
const searchInput = useRef(null);
const [address, setAddress] = useState({});
const [coords, setCoords] = useState({
lat: 42.680115925419294,
lng: 14.010667884881462,
});
// init gmap script
const initMapScript = () => {
// if script already loaded
if(window.google) {
return Promise.resolve();
}
const src = `${mapApiJs}?key=${apiKey}&libraries=places&v=weekly`;
return loadAsyncScript(src);
}
// do something on address change
const onChangeAddress = (autocomplete) => {
const place = autocomplete.getPlace();
setAddress(extractAddress(place));
setCoords({
lat: place.geometry.location.lat(),
lng: place.geometry.location.lng(),
});
}
// init autocomplete
const initAutocomplete = () => {
if (!searchInput.current) return;
const autocomplete = new window.google.maps.places.Autocomplete(searchInput.current);
autocomplete.setFields(["address_component", "geometry"]);
autocomplete.addListener("place_changed", () => onChangeAddress(autocomplete));
}
const reverseGeocode = ({ latitude: lat, longitude: lng}) => {
const url = `${geocodeJson}?key=${apiKey}&latlng=${lat},${lng}`;
searchInput.current.value = "Getting your location...";
fetch(url)
.then(response => response.json())
.then(location => {
const place = location.results[0];
const _address = extractAddress(place);
setAddress(_address);
searchInput.current.value = _address.plain();
setCoords({
lat: lat,
lng: lng,
});
})
}
const findMyLocation = () => {
if (navigator.geolocation) {
navigator.geolocation.getCurrentPosition(position => {
reverseGeocode(position.coords)
})
}
}
// load map script after mounted
useEffect(() => {
initMapScript().then(() => initAutocomplete())
}, []);
return(
<>
<form>
<div>
<div className="search">
<span><Search /></span>
<input
name="address"
ref={searchInput}
type="text"
placeholder="Search Address...."
/>
<button type="button" onClick={findMyLocation}><GpsFixed /></button>
</div>
</div>
</form>
</>
);
}
我也嘗試過使用 Material UITextField而inputRef不是標準的input,但我遇到了同樣的問題。此外,它在頁面重繪 時更頻繁地發生。在第一頁加載它幾乎每次都有效。
uj5u.com熱心網友回復:
您是否嘗試過添加searchInput.current到 的依賴項陣列useEffect?你在if (!searchInput.current) return;里面有這條線initAutocomplete,你searchInput最初設定為null. 因此,在頁面重繪 時ref,在輸入元素上設定與initAutocomplete函式運行之間可能存在競爭條件。
轉載請註明出處,本文鏈接:https://www.uj5u.com/qita/389108.html
標籤:反应 谷歌地图 材质-ui 谷歌地图自动完成 反应谷歌地方自动完成
