已配置Places库仍报错?react-places-autocomplete加载问题求助
问题解决方案
错误原因很明确:react-places-autocomplete初始化时,全局环境里的Google Maps Places库还未加载完成。虽然你在GoogleMapReact中配置了libraries: ['places'],但该组件是内部独立加载地图脚本,无法被react-places-autocomplete检测到,或者加载顺序晚于输入组件的初始化。
以下是几种可行的解决方式:
方案一:全局预加载Google Maps脚本
直接在项目的HTML入口文件(比如public/index.html)的<head>标签中添加Google Maps脚本,确保Places库在所有组件渲染前加载完成:
<script src="https://maps.googleapis.com/maps/api/js?key=%VITE_MAP_KEY%&libraries=places"></script>
注:Vite环境下可以用
%VITE_MAP_KEY%直接注入环境变量,其他框架可替换为对应变量写法。
之后可以移除GoogleMapReact中bootstrapURLKeys里的libraries配置,避免重复加载。
方案二:在PlaceInput组件中手动控制脚本加载
封装一个Hook来确保Places库加载完成后再渲染输入组件:
import { useEffect, useState } from 'react'; const useGooglePlacesLoader = () => { const [loaded, setLoaded] = useState(false); const [loadError, setLoadError] = useState(null); useEffect(() => { // 先检查是否已加载 if (window.google?.maps?.places) { setLoaded(true); return; } const script = document.createElement('script'); script.src = `https://maps.googleapis.com/maps/api/js?key=${import.meta.env.VITE_MAP_KEY}&libraries=places`; script.async = true; script.defer = true; script.onload = () => { window.google?.maps?.places ? setLoaded(true) : setLoadError(new Error('Places库加载失败')); }; script.onerror = () => setLoadError(new Error('地图脚本加载失败')); document.head.appendChild(script); return () => document.head.removeChild(script); }, []); return { loaded, loadError }; };
修改PlaceInput组件,使用这个Hook:
const PlaceInput = ({finalAddress}) => { const [address, setAddress] = useState(''); const { loaded, loadError } = useGooglePlacesLoader(); if (loadError) return <div>加载失败:{loadError.message}</div>; if (!loaded) return <div>加载中...</div>; const handleChange = address => { setAddress(address); finalAddress(address) }; const handleSelect = address => { geocodeByAddress(address) .then(results => getLatLng(results[0])) .then(latLng => console.log('Success', latLng)) .catch(error => console.error('Error', error)); }; return ( <PlacesAutocomplete value={address} onChange={handleChange} onSelect={handleSelect} > {({getInputProps, suggestions, getSuggestionItemProps, loading}) => ( <div> <input {...getInputProps({ placeholder: 'Building', className: 'location-search-input', })} /> <div className="autocomplete-dropdown-container"> // some code </div> </div> )} </PlacesAutocomplete> ); };
方案三:利用GoogleMapReact的加载回调控制渲染
在父组件中,等待GoogleMapReact加载完成后再渲染PlaceInput:
const ParentComponent = () => { const [mapsReady, setMapsReady] = useState(false); // 假设lat、lng、address等状态已定义 return ( <div> <GoogleMapReact bootstrapURLKeys={{key: import.meta.env.VITE_MAP_KEY, libraries: ['places']}} center={{lat: lat, lng: lng}} zoom={address ? 17 : 12} options={{ zoomControl: false, streetViewControl: false, mapTypeControl: false, scaleControl: false, rotateControl: false, fullscreenControl: false, keyboardShortcuts: false, clickableIcons: false, scrollwheel: false, gestureHandling: 'none', }} onGoogleApiLoaded={() => setMapsReady(true)} > <Marker address={address} lat={lat + 0.00035} lng={lng - 0.0003}/> </GoogleMapReact> {mapsReady && <PlaceInput finalAddress={/* 你的地址回调 */} />} </div> ); };
内容的提问来源于stack exchange,提问作者shadowind
相关产品推荐
相关产品推荐

