使用Google Maps API显示两点路线时地图抖动,如何修复?
解决Google Maps API地图缩放/切换时频繁重置到初始位置的问题
问题根源
- 固定坐标与视野调整冲突:你给
GoogleMap设置了固定的center={positionA}和zoom={10},但同时在onLoad回调里调用fitBounds把视野调整到包含两个坐标的范围。每次组件重渲染时,地图会先跳到固定的初始位置,再被fitBounds拉回,导致抖动。 - 路线服务重复触发:
DirectionsService直接嵌套在GoogleMap的JSX中,每次组件重渲染(比如directions状态更新)都会重新创建服务实例、发起重复请求,触发状态更新后再次重渲染,加剧地图重置问题。
修复方案
1. 移除固定的center和zoom属性
让地图通过fitBounds或DirectionsRenderer自动控制视野,避免手动设置的初始位置干扰。
2. 用useEffect控制路线请求时机
把路线请求逻辑移到useEffect中,只在组件初始化或位置坐标变化时发起一次请求,避免重复触发。
3. 补全缺失的React钩子导入
原代码中使用了useState和Fragment但未导入,需要补上。
修改后的完整代码
import { GoogleMap, useLoadScript, DirectionsRenderer } from '@react-google-maps/api'; import { Marker } from '@react-google-maps/api'; import { useState, useEffect, Fragment } from 'react'; // 补全导入 const libraries = ['places']; export default function Details() { const positionA = { lat: 41.8781, lng: -87.6298 }; const positionB = { lat: 42.8781, lng: -88.6298 }; const containerStyle = { width: '100%', height: '100%' }; const [directions, setDirections] = useState(null); const { isLoaded, loadError } = useLoadScript({ googleMapsApiKey: process.env.NEXT_PUBLIC_GMAPS_API_KEY, libraries, }); // 仅在地图加载完成后发起一次路线请求 useEffect(() => { if (!isLoaded) return; const directionsService = new window.google.maps.DirectionsService(); directionsService.route( { destination: positionB, origin: positionA, travelMode: 'DRIVING', }, (response) => { if (response.status === 'OK') { setDirections(response); } else { console.log('Directions request failed due to: ' + response.status); } } ); }, [isLoaded]); if (loadError) return "Error loading maps"; return ( <Fragment> <section className="contact-container"> <div className="detail-slot"> <div style={{ height: "calc(100% - 16rem)" }}> {isLoaded && ( <GoogleMap mapContainerStyle={containerStyle} // 移除固定的center和zoom onLoad={(map) => { const bounds = new window.google.maps.LatLngBounds(); bounds.extend(positionA); bounds.extend(positionB); map.fitBounds(bounds); }} > {positionA && <Marker position={positionA} />} {positionB && <Marker position={positionB} />} {directions && ( <DirectionsRenderer directions={directions} options={{ polylineOptions: { strokeColor: 'red', }, }} /> )} </GoogleMap> )} </div> </div> </section> </Fragment> ); }
额外说明
- 移除固定坐标后,地图会先通过
onLoad的fitBounds定位到包含两个坐标的范围,当DirectionsRenderer加载路线后,会自动调整视野覆盖整条路线,不会再出现重置抖动。 - 使用
useEffect封装路线请求,确保仅在地图加载完成后发起一次请求,避免重复触发状态更新导致的组件重渲染。
内容的提问来源于stack exchange,提问作者JeyM
相关产品推荐
相关产品推荐

