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

使用@react-google-maps/api的PolylineF首次加载地图时绘制异常

问题解决:首次加载时PolylineF出现两条折线

问题重现

使用@react-google-maps/api的PolylineF结合google.maps.DirectionsService绘制步行路径时,首次加载后第一次绘制会出现两条线:一条是预期的步行路径,另一条是两点间的直线;后续操作则正常。

问题原因

  1. 异步更新导致中间渲染:原代码中每次循环都调用setPoints更新状态,每次更新都会触发PolylineF重新渲染,可能在路径计算完成前出现临时异常渲染。
  2. 依赖缺失:useEffect未监听dirService的变化,导致dirService初始化完成后,无法自动重新执行路径计算。
  3. 未判断服务可用性:在dirService未初始化完成时就执行drawPolygon,可能导致points状态未被正确更新,触发异常渲染。

修复方案

1. 一次性收集路径点再更新状态

避免多次触发状态更新,先把所有路径点收集完成后再一次性设置points:

const drawPolygon = async (markpoints) => {
    if (!dirService) return; // 服务未就绪时直接返回
    let allPoints = [];
    for (let i = 0; i < markpoints.length - 1; i++) {
        try {
            const result = await dirService.route({ 
                origin: markpoints[i], 
                destination: markpoints[i + 1], 
                travelMode: window.google.maps.TravelMode.WALKING 
            });
            const newPoints = result.routes[0].overview_path.map(p => ({ lat: p.lat(), lng: p.lng() }));
            allPoints.push(...newPoints);
        } catch (error) {
            console.log(error.message);
        }
    }
    setPoints(allPoints); // 一次性更新所有路径点
}

2. 补全useEffect依赖项

将dirService加入useEffect的依赖数组,确保服务初始化完成后自动重新计算路径:

useEffect(() => {
    // 确保有至少两个点且服务就绪时才执行绘制
    if (markpoints.length > 1 && dirService) {
        drawPolygon(markpoints);
    }
}, [markpoints, dirService]) // 添加dirService到依赖

3. 控制PolylineF的渲染时机(可选)

添加状态控制折线的渲染,避免在路径计算过程中显示异常内容:

const [isDrawingComplete, setIsDrawingComplete] = useState(false);

const drawPolygon = async (markpoints) => {
    if (!dirService) return;
    setIsDrawingComplete(false);
    let allPoints = [];
    for (let i = 0; i < markpoints.length - 1; i++) {
        try {
            const result = await dirService.route({ 
                origin: markpoints[i], 
                destination: markpoints[i + 1], 
                travelMode: window.google.maps.TravelMode.WALKING 
            });
            const newPoints = result.routes[0].overview_path.map(p => ({ lat: p.lat(), lng: p.lng() }));
            allPoints.push(...newPoints);
        } catch (error) {
            console.log(error.message);
        }
    }
    setPoints(allPoints);
    setIsDrawingComplete(true);
}

// 渲染时只在绘制完成后显示折线
{isDrawingComplete && <PolylineF
    path={points}
    geodesic={true}
    options={{
        fillColor: "red",
        strokeColor: "#ff2527",
        strokeOpacity: 0.75,
        strokeWeight: 2,
    }}
/>}

完整修复后代码

const PolygonOnMap = ({ markpoints, close, remove, getPoints, readOnly, ss }) => {
    const { isLoaded } = useContext(GoogleMapAPIContext)
    const [points, setPoints] = useState([])
    const [isDrawingComplete, setIsDrawingComplete] = useState(false)
    const dirService = useMemo(()=>{
        console.log('useMemo',isLoaded);
        if(isLoaded)
            return new window.google.maps.DirectionsService();
        return null;
    },[isLoaded])

    const drawPolygon = async (markpoints) => {
        if (!dirService) return;
        setIsDrawingComplete(false);
        let allPoints = [];
        for (let i = 0; i < markpoints.length - 1; i++) {
            try {
                const result = await dirService.route({ 
                    origin: markpoints[i], 
                    destination: markpoints[i + 1], 
                    travelMode: window.google.maps.TravelMode.WALKING 
                });
                const newPoints = result.routes[0].overview_path.map(p => ({ lat: p.lat(), lng: p.lng() }));
                allPoints.push(...newPoints);
            } catch (error) {
                console.log(error.message);
            }
        }
        setPoints(allPoints);
        setIsDrawingComplete(true);
    }

    useEffect(() => {
        if (markpoints.length > 1 && dirService) {
            drawPolygon(markpoints);
        }
    }, [markpoints, dirService])

    return (
        <div>
            {markpoints.map((p, i) => <MarkerF key={i} position={p} index={i} />)}
            {isDrawingComplete && <PolylineF
                path={points}
                geodesic={true}
                options={{
                    fillColor: "red",
                    strokeColor: "#ff2527",
                    strokeOpacity: 0.75,
                    strokeWeight: 2,
                }}
            />}
        </div>
    )
}

export default PolygonOnMap

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.06 07:29:54