如何避免父组件状态更新时Google Map重置中心与缩放设置?
解决Google Map父组件重渲染时重置视角的问题
问题根源在于你用了defaultCenter和defaultZoom,这俩是地图组件首次挂载时才生效的初始配置。当父组件更新info状态触发重渲染时,MapComponent跟着重新渲染,地图就会回到初始的中心和缩放值。
直接改成受控模式就能搞定,步骤如下:
- 在MapComponent里新增状态保存当前地图的中心坐标和缩放级别
- 监听地图的
onCameraChanged事件,实时更新这两个状态 - 把Map组件的
center和zoom属性绑定到我们的状态上,替换原来的defaultCenter和defaultZoom
修改后的MapComponent代码:
import React, { useEffect, useState, useCallback } from "react"; import { APIProvider, Map, AdvancedMarker } from "@vis.gl/react-google-maps"; import Axios from "axios"; export default function MapComponent({ updateSidebar }) { const [markers, setMarkers] = useState([]); // 新增状态保存当前地图视角 const [mapView, setMapView] = useState({ center: { lat: -23.698, lng: 133.8807 }, zoom: 4 }); useEffect(() => { const getElectorates = async () => { try { const elecs = await Axios.get("http://localhost:3930/admin/getMapData"); setMarkers(elecs.data); } catch (err) { console.log(err); } }; getElectorates(); }, []); // 监听地图视角变化,更新状态 const handleCameraChange = useCallback((event) => { const { center, zoom } = event.detail; setMapView({ center: { lat: center.lat(), lng: center.lng() }, zoom: Math.round(zoom) }); }, []); return ( <APIProvider apiKey="<redacted>"> <Map style={{ width: "650px", height: "650px", maxWidth: "80vw", maxHeight: "80vh", }} // 替换default属性为受控状态 center={mapView.center} zoom={mapView.zoom} gestureHandling="greedy" disableDefaultUI={true} mapId="<redacted>" // 添加视角变化监听 onCameraChanged={handleCameraChange} > {markers.map((el) => { return ( <AdvancedMarker position={el.coords} key={el.electorate} // 用唯一标识当key,比索引更稳妥 onClick={() => { updateSidebar(el.electorate); }} /> ); })} </Map> </APIProvider> ); }
额外提个小优化:把marker的key从索引改成el.electorate,这样当markers数组变化时,React能更高效地更新DOM,避免不必要的重渲染。
内容的提问来源于stack exchange,提问作者jpryor
相关产品推荐
相关产品推荐

