Expo React Native打车应用Google Directions API请求量过高优化咨询
React Native打车应用Google Directions API请求过量优化方案
核心问题根源
你的代码触发过量请求的原因有两点:
- 监听
lastLocation的useEffect会在司机位置每次更新时直接调用fitMap触发API请求 - 20秒一次的定时器也会在位置变化时重复调用
fitMap请求路线
同时每次请求都会覆盖liveRouteCoords,导致旧轨迹被清除。
优化方案
优化逻辑核心为:仅在订单状态切换的第一时间请求路线,后续位置更新仅调整地图视口不触发接口调用,可按需设置长间隔刷新到达时间,避免配额浪费。
第一步:新增辅助状态
// 存储当前行程的固定目标点 const [currentDest, setCurrentDest] = useState(null); // 标记当前阶段是否已经请求过路线 const [routeFetched, setRouteFetched] = useState(false);
第二步:修改位置监听useEffect
useEffect(() => { // 订单状态变为接受时,仅首次请求到乘客的路线 if (curBooking?.status == 'ACCEPTED' && !routeFetched && lastLocation) { const dest = { lat: curBooking.pickup.lat, lng: curBooking.pickup.lng }; setCurrentDest(dest); fitMap(lastLocation, dest, true); setRouteFetched(true); setlastCoords(lastLocation); return; } // 司机到达上车点时重置路线状态 if (curBooking?.status == 'ARRIVED') { setlastCoords(null); setRouteFetched(false); setCurrentDest(null); setTimeout(() => { mapRef.current.fitToCoordinates([{ latitude: curBooking.pickup.lat, longitude: curBooking.pickup.lng }, { latitude: curBooking.drop.lat, longitude: curBooking.drop.lng }], { edgePadding: { top: 40, right: 40, bottom: 40, left: 40 }, animated: true, }) }, 1000); return; } // 订单开始行程时,仅首次请求到目的地的路线 if (curBooking?.status == 'STARTED' && !routeFetched && lastLocation) { const dest = { lat: curBooking.drop.lat, lng: curBooking.drop.lng }; setCurrentDest(dest); fitMap(lastLocation, dest, true); setRouteFetched(true); setlastCoords(lastLocation); return; } // 后续位置更新仅调整视口,不请求路线 if (lastLocation && currentDest && routeFetched) { mapRef.current.fitToCoordinates([{ latitude: lastLocation.lat, longitude: lastLocation.lng }, { latitude: currentDest.lat, longitude: currentDest.lng }], { edgePadding: { top: 40, right: 40, bottom: 40, left: 40 }, animated: true, }) setlastCoords(lastLocation); } // 乘客端到达后的视口调整逻辑保持不变 if (lastLocation && curBooking?.status == 'REACHED' && role == 'rider') { setTimeout(() => { mapRef.current.fitToCoordinates([{ latitude: curBooking.pickup.lat, longitude: curBooking.pickup.lng }, { latitude: lastLocation.lat, longitude: lastLocation.lng }], { edgePadding: { top: 40, right: 40, bottom: 40, left: 40 }, animated: true, }) }, 1000); } }, [lastLocation, curBooking])
第三步:修改定时器逻辑
useEffect(() => { // 可将间隔拉长到2分钟,仅用于更新到达时间,不需要可以直接删除定时器 const interval = setInterval(() => { if (pageActive.current && curBooking && lastLocation && currentDest && routeFetched) { fitMap(lastLocation, currentDest, true); } }, 120000); // 组件卸载时清理定时器避免内存泄漏 return () => clearInterval(interval); }, [currentDest, routeFetched]);
第四步:改造fitMap函数
// 新增fetchRoute参数控制是否触发接口请求 const fitMap = (point1, point2, fetchRoute = false) => { if (fetchRoute) { let startLoc = `"${point1.lat},${point1.lng}"`; let destLoc = `"${point2.lat},${point2.lng}"`; getRouteDetails(Platform.OS, startLoc, destLoc).then((details) => { setArrivalTime(details.duration ? parseFloat(details.duration / 60).toFixed(0) : 0); let points = Polyline.decode(details.polylinePoints); let coords = points.map((point) => ({ latitude: point[0], longitude: point[1] })) // 若要保留历史行驶轨迹,改为 setLiveRouteCoords(prev => [...prev, ...coords]) setLiveRouteCoords(coords); // 调整地图视口 mapRef.current.fitToCoordinates([{ latitude: point1.lat, longitude: point1.lng }, { latitude: point2.lat, longitude: point2.lng }], { edgePadding: { top: 40, right: 40, bottom: 40, left: 40 }, animated: true, }) }); } else { // 不需要请求接口时仅调整视口 mapRef.current.fitToCoordinates([{ latitude: point1.lat, longitude: point1.lng }, { latitude: point2.lat, longitude: point2.lng }], { edgePadding: { top: 40, right: 40, bottom: 40, left: 40 }, animated: true, }) } }
效果说明
调整后请求量至少减少90%,如果不需要动态更新到达时间可直接删除定时器,全程仅请求2次路线(去上车点、去目的地)即可。
内容的提问来源于stack exchange,提问作者hesham79
相关产品推荐
相关产品推荐

