You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

GoogleMapReact的onGoogleApiLoaded在state变化时不重新渲染如何解决

问题原因

onGoogleApiLoaded 仅在谷歌地图API首次加载完成时触发一次,你在其中创建的Circle实例没有被持久化存储,后续state变更时也没有对应的更新逻辑触发,因此样式不会同步变化。

解决方案

  1. 用useRef存储地图实例、maps对象和所有圆圈实例的引用,避免重复创建,同时方便后续更新操作
  2. 拆分初始化创建圆圈和更新圆圈属性的逻辑
  3. 通过useEffect监听依赖项(比如tag、geoFencesSites)的变化,依赖变更时批量更新所有圆圈的属性

修改后的代码示例:

import { useRef, useEffect, useState } from 'react'
import _ from 'lodash'
import GoogleMapReact from 'google-map-react'

// 其他原有业务逻辑保留
const tags = [allJobsTag].concat(settings.jobs.filter((job) => !job.deleted));
const [tag, setTag] = useState(allJobsTag);
// 新增ref存储必要引用
const mapRef = useRef(null)
const mapsRef = useRef(null)
const circlesRef = useRef([])

function renderGeoFences() {
    const map = mapRef.current
    const maps = mapsRef.current
    if (!map || !maps) return
    // 清空之前的圆圈实例,避免重复渲染
    circlesRef.current.forEach(circle => circle.setMap(null))
    circlesRef.current = []
    // 重新创建所有圆圈
    _.map(geoFencesSites, (site) => {
        let circle = new maps.Circle({
            strokeColor: tag.id==='all-jobs'?"orange":'#1aba8b26',
            strokeOpacity: 1,
            strokeWeight: 4,
            fillColor: '#1aba8b1f',
            fillOpacity: 1,
            map,
            center: { lat: Number(site.location.latitude), lng: Number(site.location.longitude) },
            radius: site.fenceSize,
        });
        circlesRef.current.push(circle)
    });
}

let apiIsLoaded = (map, maps) => {
    // 存储实例到ref
    mapRef.current = map
    mapsRef.current = maps
    renderGeoFences();
};

// 新增useEffect,依赖变化时触发重新渲染围栏
useEffect(() => {
    renderGeoFences()
}, [tag, geoFencesSites]) // 所有影响围栏渲染的变量都要加入依赖数组

return(
    <GoogleMapReact
        zoom={getMapZoom()}
        center={{ lat: centerLatitude, lng: centerLongitude }}
        options={{
            fullscreenControl: false,
            zoomControlOptions: { position: 3 },
        }}
        yesIWantToUseGoogleMapApiInternals
        onGoogleApiLoaded={({ map, maps }) => apiIsLoaded(map, maps)}
    >
        {renderAddresses()}
        {renderUsersLocation()}
        {renderHighlightedUserRoute()}
    </GoogleMapReact>
)

性能优化方案

如果只是修改样式不需要重建圆圈,可以直接调用Circle实例的setOptions方法更新属性,避免销毁重建的性能开销:

useEffect(() => {
  if (!circlesRef.current.length) return
  const newStrokeColor = tag.id==='all-jobs'?"orange":'#1aba8b26'
  circlesRef.current.forEach(circle => {
    circle.setOptions({
      strokeColor: newStrokeColor
    })
  })
}, [tag])

内容的提问来源于stack exchange,提问作者Zusman

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.10.09 21:09:02