43 lines
1.3 KiB
TypeScript
43 lines
1.3 KiB
TypeScript
import { useCallback, useRef, useState } from "react";
|
|
import type { TrendPoint } from "../../shared/api";
|
|
|
|
export function useTrend(targetId: number | null) {
|
|
const [data, setData] = useState<TrendPoint[]>([]);
|
|
const [error, setError] = useState<string | null>(null);
|
|
const [loading, setLoading] = useState(false);
|
|
const abortRef = useRef<AbortController | null>(null);
|
|
|
|
const fetchTrend = useCallback(
|
|
async (from: string, to: string) => {
|
|
if (targetId === null) return;
|
|
|
|
abortRef.current?.abort();
|
|
const controller = new AbortController();
|
|
abortRef.current = controller;
|
|
|
|
setLoading(true);
|
|
setError(null);
|
|
|
|
try {
|
|
const response = await fetch(
|
|
`/api/targets/${targetId}/trend?from=${encodeURIComponent(from)}&to=${encodeURIComponent(to)}`,
|
|
{ signal: controller.signal },
|
|
);
|
|
|
|
if (!response.ok) throw new Error(`HTTP ${response.status}`);
|
|
|
|
const result = (await response.json()) as TrendPoint[];
|
|
setData(result);
|
|
} catch (err) {
|
|
if (err instanceof DOMException && err.name === "AbortError") return;
|
|
setError(err instanceof Error ? err.message : "请求失败");
|
|
} finally {
|
|
setLoading(false);
|
|
}
|
|
},
|
|
[targetId],
|
|
);
|
|
|
|
return { data, error, loading, fetchTrend };
|
|
}
|