src/robotaxi/pages/begin-route/hooks/use-vehicle-tracking.ts
@@ -185,11 +185,23 @@ // 降低车辆位置更新频率 return; } if (Number.isFinite(lat) && Number.isFinite(lng)) { lastVehiclePointRef.current = { latitude: lat, longitude: lng }; lastVehicleUpdateAtRef.current = now; setVehicleLocation({ latitude: lat, longitude: lng }); if (!Number.isFinite(lat) || !Number.isFinite(lng)) { return; } const lastPoint = lastVehiclePointRef.current; // 坐标与上次一致时跳过 setState:避免静止 / 重复点位推送产生无效重渲染 // (朝向变化由 vehicleDirection 单独驱动,不依赖此处的 vehicleLocation 写入)。 if ( lastPoint && Math.abs(lastPoint.latitude - lat) <= VEHICLE_LOCATION_EPSILON && Math.abs(lastPoint.longitude - lng) <= VEHICLE_LOCATION_EPSILON ) { lastVehicleUpdateAtRef.current = now; return; } lastVehiclePointRef.current = { latitude: lat, longitude: lng }; lastVehicleUpdateAtRef.current = now; setVehicleLocation({ latitude: lat, longitude: lng }); }; useEffect(() => { src/robotaxi/pages/begin-route/hooks/use-web-socket-events.ts
@@ -65,10 +65,20 @@ setRouteDistance: (value: any) => void; setRouteDuration: (value: number | null) => void; setModifyDestinationSocketStatus: (value: number | null) => void; setOrderRouteMetrics?: (metrics: { distanceMeters: number | null; durationSeconds: number | null; }) => void; setOrderRouteMetrics?: ( metrics: | { distanceMeters: number | null; durationSeconds: number | null; } | ((prev: { distanceMeters: number | null; durationSeconds: number | null; }) => { distanceMeters: number | null; durationSeconds: number | null; }) ) => void; setBeforeUserEndSite: (site: { longitude: number; latitude: number } | null) => void; setHasPreviousOrder: (value: boolean) => void; isModifyDestinationReviewVisible?: boolean; src/robotaxi/pages/begin-route/hooks/web-socket-handlers/create-order-route-socket-handler.ts
@@ -70,16 +70,31 @@ const durationSecondsRaw = Number(route?.duration); const distanceKm = normalizeDistanceKm(distanceMeters); if (distanceKm !== null) { deps.setRouteDistance(distanceKm); // 行程中后端会持续推送 ORDER_ROUTE(车辆静止时也在上报),normalizeDistanceKm 每次都会返回新对象, // 直接 setRouteDistance 会让每条消息都因新引用触发无效重渲染。这里用函数式更新做按值去重: // value/unit 未变化时返回旧引用,React 据此跳过本次重渲染。 deps.setRouteDistance((prev: { value: number; unit: 'km' | 'm' } | null) => prev && prev.value === distanceKm.value && prev.unit === distanceKm.unit ? prev : distanceKm ); } const durationSeconds = normalizeDurationSeconds(durationSecondsRaw); if (durationSeconds !== null) { // number:值相同时 React 自动跳过重渲染,无需额外去重。 deps.setRouteDuration(durationSeconds); } deps.setOrderRouteMetrics?.({ distanceMeters: Number.isFinite(distanceMeters) ? distanceMeters : null, durationSeconds: Number.isFinite(durationSecondsRaw) ? durationSecondsRaw : null }); const nextDistanceMeters = Number.isFinite(distanceMeters) ? distanceMeters : null; const nextDurationSeconds = Number.isFinite(durationSecondsRaw) ? durationSecondsRaw : null; // orderRouteMetrics 同理:函数式更新按值去重,未变化保持旧引用以跳过重渲染。 deps.setOrderRouteMetrics?.((prev) => prev && prev.distanceMeters === nextDistanceMeters && prev.durationSeconds === nextDurationSeconds ? prev : { distanceMeters: nextDistanceMeters, durationSeconds: nextDurationSeconds } ); }; /**