// src/views/Company/components/CompanyOverview/hooks/useDisclosureData.ts // 披露日程数据 Hook - 用于工商信息 Tab import { useState, useEffect, useRef } from "react"; import { logger } from "@utils/logger"; import axios from "@utils/axiosConfig"; import type { DisclosureSchedule } from "../types"; interface ApiResponse { success: boolean; data: T; } // 支持延迟加载的配置选项 interface UseDisclosureDataOptions { stockCode?: string; /** 是否启用数据加载,默认 true */ enabled?: boolean; } interface UseDisclosureDataResult { disclosureSchedule: DisclosureSchedule[]; loading: boolean; error: string | null; } /** * 披露日程数据 Hook(支持延迟加载) * @param options - 配置选项 * @param options.stockCode - 股票代码 * @param options.enabled - 是否启用数据加载,默认 true */ export const useDisclosureData = (options: UseDisclosureDataOptions): UseDisclosureDataResult => { const { stockCode, enabled = true } = options; const [disclosureSchedule, setDisclosureSchedule] = useState([]); const [loading, setLoading] = useState(true); const [error, setError] = useState(null); // 使用 ref 跟踪是否已加载,避免 Tab 切换时重复请求 const hasLoadedRef = useRef(false); // 记录上次加载的 stockCode,stockCode 变化时需要重新加载 const lastStockCodeRef = useRef(undefined); useEffect(() => { // 只有 enabled 且有 stockCode 时才请求 if (!enabled || !stockCode) { setLoading(false); return; } // stockCode 变化时重置加载状态 if (lastStockCodeRef.current !== stockCode) { hasLoadedRef.current = false; lastStockCodeRef.current = stockCode; } // 如果已经加载过数据,不再重新请求(Tab 切换回来时保持缓存) if (hasLoadedRef.current) { setLoading(false); return; } const controller = new AbortController(); const loadData = async () => { setLoading(true); setError(null); try { const { data: result } = await axios.get>( `/api/stock/${stockCode}/disclosure-schedule`, { signal: controller.signal } ); if (result.success) { setDisclosureSchedule(result.data); } else { setError("加载披露日程数据失败"); } setLoading(false); hasLoadedRef.current = true; } catch (err: any) { // 请求被取消时,不更新任何状态 if (err.name === "CanceledError") { return; } logger.error("useDisclosureData", "loadData", err, { stockCode }); setError("网络请求失败"); setLoading(false); hasLoadedRef.current = true; } }; loadData(); return () => controller.abort(); }, [stockCode, enabled]); const isLoading = loading || (enabled && !hasLoadedRef.current && !error); return { disclosureSchedule, loading: isLoading, error }; };