fix(dashboard): useDashboard 加请求世代校验 — 快速连续切换时间范围时并发 get_summary 响应可能乱序返回导致标签与数据错位;参照 useUsageQuery 的 genRef 模式丢弃过期响应(data/loadStats/error/loading 全部受保护),卸载时使世代失效

This commit is contained in:
KimiSwitch Dev committed 2026-10-08 00:28:39 +08:00
1 parent f9f9af0fc9
commit 803c346854
1 file changed
+14 -2
+14 -2
View File
@@ -1,4 +1,4 @@
import { useCallback, useEffect, useState } from "react";
import { useCallback, useEffect, useRef, useState } from "react";
import { invoke } from "@tauri-apps/api/core";
import type { SummaryResult } from "../types/dashboard";
@@ -24,8 +24,11 @@ export function useDashboard() {
const [error, setError] = useState<string | null>(null);
/** Round-trip timing for the last get_summary call (user-perceived lag). */
const [loadStats, setLoadStats] = useState<{ ms: number } | null>(null);
// Generation counter: stale responses (superseded range / unmounted) are dropped.
const genRef = useRef(0);
const refresh = useCallback(async (force = false) => {
const gen = ++genRef.current;
setLoading(true);
setError(null);
const start = performance.now();
@@ -34,13 +37,15 @@ export function useDashboard() {
range,
refresh: force,
});
if (genRef.current !== gen) return;
setData(result);
setLoadStats({ ms: Math.round(performance.now() - start) });
} catch (err) {
if (genRef.current !== gen) return;
const msg = err instanceof Error ? err.message : String(err);
setError(msg);
} finally {
setLoading(false);
if (genRef.current === gen) setLoading(false);
}
}, [range]);
@@ -48,6 +53,13 @@ export function useDashboard() {
refresh();
}, [refresh]);
// Ignore late responses after unmount.
useEffect(() => {
return () => {
genRef.current += 1;
};
}, []);
const changeRange = useCallback((next: DashboardRange) => {
setRange(next);
try {