/** * Custom hook for fetching historical celestial data */ import { useState, useEffect, useRef } from 'react'; import { fetchCelestialPositions } from '../utils/api'; import type { CelestialBody } from '../types'; export function useHistoricalData(selectedDate: Date | null) { const [bodies, setBodies] = useState([]); const [loading, setLoading] = useState(false); const [error, setError] = useState(null); // 使用 ref 跟踪上次请求的时间,避免重复请求 const lastFetchedDateRef = useRef(null); useEffect(() => { if (!selectedDate) { return; } // Track if this effect instance is active let isActive = true; // 创建午夜时间戳 const targetDate = new Date(selectedDate); targetDate.setUTCHours(0, 0, 0, 0); const dateKey = targetDate.toISOString(); // 如果是同一个时间点,不重复请求 if (lastFetchedDateRef.current === dateKey) { return; } const loadHistoricalData = async () => { try { setLoading(true); setError(null); console.log(`[useHistoricalData] Fetching data for ${dateKey}`); // Set start and end to the same time to get a single snapshot const data = await fetchCelestialPositions( targetDate.toISOString(), targetDate.toISOString(), // Same as start - single point in time '1d' ); // Only update state if this effect is still active if (isActive) { setBodies(data.bodies); lastFetchedDateRef.current = dateKey; // 记录已请求的时间 console.log(`[useHistoricalData] Loaded ${data.bodies.length} bodies`); setLoading(false); } else { console.log(`[useHistoricalData] Ignored stale data for ${dateKey}`); } } catch (err) { if (isActive) { console.error('Failed to fetch historical data:', err); setError(err instanceof Error ? err.message : 'Unknown error'); setLoading(false); } } }; loadHistoricalData(); // Cleanup function return () => { isActive = false; }; }, [selectedDate]); return { bodies, loading, error }; }