fix(dashboard): useDashboard 加请求世代校验 — 快速连续切换时间范围时并发 get_summary 响应可能乱序返回导致标签与数据错位;参照 useUsageQuery 的 genRef 模式丢弃过期响应(data/loadStats/error/loading 全部受保护),卸载时使世代失效
This commit is contained in:
1 parent
f9f9af0fc9
commit
803c346854
1 file changed
+14
-2
@@ -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 { invoke } from "@tauri-apps/api/core";
|
||||||
import type { SummaryResult } from "../types/dashboard";
|
import type { SummaryResult } from "../types/dashboard";
|
||||||
|
|
||||||
@@ -24,8 +24,11 @@ export function useDashboard() {
|
|||||||
const [error, setError] = useState<string | null>(null);
|
const [error, setError] = useState<string | null>(null);
|
||||||
/** Round-trip timing for the last get_summary call (user-perceived lag). */
|
/** Round-trip timing for the last get_summary call (user-perceived lag). */
|
||||||
const [loadStats, setLoadStats] = useState<{ ms: number } | null>(null);
|
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 refresh = useCallback(async (force = false) => {
|
||||||
|
const gen = ++genRef.current;
|
||||||
setLoading(true);
|
setLoading(true);
|
||||||
setError(null);
|
setError(null);
|
||||||
const start = performance.now();
|
const start = performance.now();
|
||||||
@@ -34,13 +37,15 @@ export function useDashboard() {
|
|||||||
range,
|
range,
|
||||||
refresh: force,
|
refresh: force,
|
||||||
});
|
});
|
||||||
|
if (genRef.current !== gen) return;
|
||||||
setData(result);
|
setData(result);
|
||||||
setLoadStats({ ms: Math.round(performance.now() - start) });
|
setLoadStats({ ms: Math.round(performance.now() - start) });
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
|
if (genRef.current !== gen) return;
|
||||||
const msg = err instanceof Error ? err.message : String(err);
|
const msg = err instanceof Error ? err.message : String(err);
|
||||||
setError(msg);
|
setError(msg);
|
||||||
} finally {
|
} finally {
|
||||||
setLoading(false);
|
if (genRef.current === gen) setLoading(false);
|
||||||
}
|
}
|
||||||
}, [range]);
|
}, [range]);
|
||||||
|
|
||||||
@@ -48,6 +53,13 @@ export function useDashboard() {
|
|||||||
refresh();
|
refresh();
|
||||||
}, [refresh]);
|
}, [refresh]);
|
||||||
|
|
||||||
|
// Ignore late responses after unmount.
|
||||||
|
useEffect(() => {
|
||||||
|
return () => {
|
||||||
|
genRef.current += 1;
|
||||||
|
};
|
||||||
|
}, []);
|
||||||
|
|
||||||
const changeRange = useCallback((next: DashboardRange) => {
|
const changeRange = useCallback((next: DashboardRange) => {
|
||||||
setRange(next);
|
setRange(next);
|
||||||
try {
|
try {
|
||||||
|
|||||||
Reference in new issue
Block a user