From 298ac5a335f70379a9b97606d76e2a09738605c5 Mon Sep 17 00:00:00 2001 From: zdl <3489966805@qq.com> Date: Fri, 19 Dec 2025 18:53:30 +0800 Subject: [PATCH] =?UTF-8?q?perf(CompanyOverview):=20hooks=20=E6=94=AF?= =?UTF-8?q?=E6=8C=81=20enabled=20=E5=BB=B6=E8=BF=9F=E5=8A=A0=E8=BD=BD?= =?UTF-8?q?=E5=92=8C=E5=88=B7=E6=96=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - 所有 hooks 参数改为 options 对象形式 - 新增 enabled 参数支持延迟加载 - 新增 refreshKey 参数支持手动刷新 - 智能初始化 loading 状态,避免首次渲染闪现空状态 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude --- .../hooks/useAnnouncementsData.ts | 25 +++++++++--- .../CompanyOverview/hooks/useBasicInfo.ts | 25 +++++++++--- .../CompanyOverview/hooks/useBranchesData.ts | 40 ++++++++++++++----- .../hooks/useDisclosureData.ts | 22 +++++++--- .../hooks/useManagementData.ts | 33 +++++++++++---- .../hooks/useShareholderData.ts | 25 +++++++++--- 6 files changed, 132 insertions(+), 38 deletions(-) diff --git a/src/views/Company/components/CompanyOverview/hooks/useAnnouncementsData.ts b/src/views/Company/components/CompanyOverview/hooks/useAnnouncementsData.ts index ca26c6a0..0b7a2ef2 100644 --- a/src/views/Company/components/CompanyOverview/hooks/useAnnouncementsData.ts +++ b/src/views/Company/components/CompanyOverview/hooks/useAnnouncementsData.ts @@ -11,6 +11,15 @@ interface ApiResponse { data: T; } +// 支持延迟加载的配置选项 +interface UseAnnouncementsDataOptions { + stockCode?: string; + /** 是否启用数据加载,默认 true */ + enabled?: boolean; + /** 刷新标识,变化时触发重新请求 */ + refreshKey?: number; +} + interface UseAnnouncementsDataResult { announcements: Announcement[]; loading: boolean; @@ -18,16 +27,22 @@ interface UseAnnouncementsDataResult { } /** - * 公告数据 Hook - * @param stockCode - 股票代码 + * 公告数据 Hook(支持延迟加载和刷新) + * @param options - 配置选项 + * @param options.stockCode - 股票代码 + * @param options.enabled - 是否启用数据加载,默认 true + * @param options.refreshKey - 刷新标识,变化时触发重新请求 */ -export const useAnnouncementsData = (stockCode?: string): UseAnnouncementsDataResult => { +export const useAnnouncementsData = (options: UseAnnouncementsDataOptions): UseAnnouncementsDataResult => { + const { stockCode, enabled = true, refreshKey } = options; + const [announcements, setAnnouncements] = useState([]); const [loading, setLoading] = useState(false); const [error, setError] = useState(null); useEffect(() => { - if (!stockCode) return; + // 只有 enabled 且有 stockCode 时才请求 + if (!enabled || !stockCode) return; const controller = new AbortController(); @@ -57,7 +72,7 @@ export const useAnnouncementsData = (stockCode?: string): UseAnnouncementsDataRe loadData(); return () => controller.abort(); - }, [stockCode]); + }, [stockCode, enabled, refreshKey]); return { announcements, loading, error }; }; diff --git a/src/views/Company/components/CompanyOverview/hooks/useBasicInfo.ts b/src/views/Company/components/CompanyOverview/hooks/useBasicInfo.ts index 476b52d6..b66a6db3 100644 --- a/src/views/Company/components/CompanyOverview/hooks/useBasicInfo.ts +++ b/src/views/Company/components/CompanyOverview/hooks/useBasicInfo.ts @@ -11,6 +11,13 @@ interface ApiResponse { data: T; } +// 支持延迟加载的配置选项 +interface UseBasicInfoOptions { + stockCode?: string; + /** 是否启用数据加载,默认 true */ + enabled?: boolean; +} + interface UseBasicInfoResult { basicInfo: BasicInfo | null; loading: boolean; @@ -18,16 +25,22 @@ interface UseBasicInfoResult { } /** - * 公司基本信息 Hook - * @param stockCode - 股票代码 + * 公司基本信息 Hook(支持延迟加载) + * @param options - 配置选项 + * @param options.stockCode - 股票代码 + * @param options.enabled - 是否启用数据加载,默认 true */ -export const useBasicInfo = (stockCode?: string): UseBasicInfoResult => { +export const useBasicInfo = (options: UseBasicInfoOptions): UseBasicInfoResult => { + const { stockCode, enabled = true } = options; + const [basicInfo, setBasicInfo] = useState(null); - const [loading, setLoading] = useState(false); + // 智能初始化 loading:当需要加载数据时,初始值为 true,避免首次渲染闪现空状态 + const [loading, setLoading] = useState(() => enabled && !!stockCode); const [error, setError] = useState(null); useEffect(() => { - if (!stockCode) return; + // 只有 enabled 且有 stockCode 时才请求 + if (!enabled || !stockCode) return; const controller = new AbortController(); @@ -57,7 +70,7 @@ export const useBasicInfo = (stockCode?: string): UseBasicInfoResult => { loadData(); return () => controller.abort(); - }, [stockCode]); + }, [stockCode, enabled]); return { basicInfo, loading, error }; }; diff --git a/src/views/Company/components/CompanyOverview/hooks/useBranchesData.ts b/src/views/Company/components/CompanyOverview/hooks/useBranchesData.ts index f50b72fb..65299387 100644 --- a/src/views/Company/components/CompanyOverview/hooks/useBranchesData.ts +++ b/src/views/Company/components/CompanyOverview/hooks/useBranchesData.ts @@ -11,6 +11,13 @@ interface ApiResponse { data: T; } +// 支持延迟加载的配置选项 +interface UseBranchesDataOptions { + stockCode?: string; + /** 是否启用数据加载,默认 true */ + enabled?: boolean; +} + interface UseBranchesDataResult { branches: Branch[]; loading: boolean; @@ -18,16 +25,24 @@ interface UseBranchesDataResult { } /** - * 分支机构数据 Hook - * @param stockCode - 股票代码 + * 分支机构数据 Hook(支持延迟加载) + * @param options - 配置选项 + * @param options.stockCode - 股票代码 + * @param options.enabled - 是否启用数据加载,默认 true */ -export const useBranchesData = (stockCode?: string): UseBranchesDataResult => { +export const useBranchesData = (options: UseBranchesDataOptions): UseBranchesDataResult => { + const { stockCode, enabled = true } = options; + const [branches, setBranches] = useState([]); - const [loading, setLoading] = useState(false); + const [loading, setLoading] = useState(true); const [error, setError] = useState(null); + const [hasLoaded, setHasLoaded] = useState(false); useEffect(() => { - if (!stockCode) return; + if (!enabled || !stockCode) { + setLoading(false); + return; + } const controller = new AbortController(); @@ -46,18 +61,25 @@ export const useBranchesData = (stockCode?: string): UseBranchesDataResult => { } else { setError("加载分支机构数据失败"); } + setLoading(false); + setHasLoaded(true); } catch (err: any) { - if (err.name === "CanceledError") return; + // 请求被取消时,不更新任何状态 + if (err.name === "CanceledError") { + return; + } logger.error("useBranchesData", "loadData", err, { stockCode }); setError("网络请求失败"); - } finally { setLoading(false); + setHasLoaded(true); } }; loadData(); return () => controller.abort(); - }, [stockCode]); + }, [stockCode, enabled]); - return { branches, loading, error }; + const isLoading = loading || (enabled && !hasLoaded && !error); + + return { branches, loading: isLoading, error }; }; diff --git a/src/views/Company/components/CompanyOverview/hooks/useDisclosureData.ts b/src/views/Company/components/CompanyOverview/hooks/useDisclosureData.ts index 31a9e185..b506251a 100644 --- a/src/views/Company/components/CompanyOverview/hooks/useDisclosureData.ts +++ b/src/views/Company/components/CompanyOverview/hooks/useDisclosureData.ts @@ -11,6 +11,13 @@ interface ApiResponse { data: T; } +// 支持延迟加载的配置选项 +interface UseDisclosureDataOptions { + stockCode?: string; + /** 是否启用数据加载,默认 true */ + enabled?: boolean; +} + interface UseDisclosureDataResult { disclosureSchedule: DisclosureSchedule[]; loading: boolean; @@ -18,16 +25,21 @@ interface UseDisclosureDataResult { } /** - * 披露日程数据 Hook - * @param stockCode - 股票代码 + * 披露日程数据 Hook(支持延迟加载) + * @param options - 配置选项 + * @param options.stockCode - 股票代码 + * @param options.enabled - 是否启用数据加载,默认 true */ -export const useDisclosureData = (stockCode?: string): UseDisclosureDataResult => { +export const useDisclosureData = (options: UseDisclosureDataOptions): UseDisclosureDataResult => { + const { stockCode, enabled = true } = options; + const [disclosureSchedule, setDisclosureSchedule] = useState([]); const [loading, setLoading] = useState(false); const [error, setError] = useState(null); useEffect(() => { - if (!stockCode) return; + // 只有 enabled 且有 stockCode 时才请求 + if (!enabled || !stockCode) return; const controller = new AbortController(); @@ -57,7 +69,7 @@ export const useDisclosureData = (stockCode?: string): UseDisclosureDataResult = loadData(); return () => controller.abort(); - }, [stockCode]); + }, [stockCode, enabled]); return { disclosureSchedule, loading, error }; }; diff --git a/src/views/Company/components/CompanyOverview/hooks/useManagementData.ts b/src/views/Company/components/CompanyOverview/hooks/useManagementData.ts index 8dca8d70..80ca61fd 100644 --- a/src/views/Company/components/CompanyOverview/hooks/useManagementData.ts +++ b/src/views/Company/components/CompanyOverview/hooks/useManagementData.ts @@ -11,6 +11,13 @@ interface ApiResponse { data: T; } +// 支持延迟加载的配置选项 +interface UseManagementDataOptions { + stockCode?: string; + /** 是否启用数据加载,默认 true */ + enabled?: boolean; +} + interface UseManagementDataResult { management: Management[]; loading: boolean; @@ -18,16 +25,23 @@ interface UseManagementDataResult { } /** - * 管理团队数据 Hook - * @param stockCode - 股票代码 + * 管理团队数据 Hook(支持延迟加载) + * @param options - 配置选项 + * @param options.stockCode - 股票代码 + * @param options.enabled - 是否启用数据加载,默认 true */ -export const useManagementData = (stockCode?: string): UseManagementDataResult => { +export const useManagementData = (options: UseManagementDataOptions): UseManagementDataResult => { + const { stockCode, enabled = true } = options; + const [management, setManagement] = useState([]); - const [loading, setLoading] = useState(false); + const [loading, setLoading] = useState(() => enabled && !!stockCode); const [error, setError] = useState(null); + // 记录是否已完成首次加载,用于派生 loading 状态 + const [hasLoaded, setHasLoaded] = useState(false); useEffect(() => { - if (!stockCode) return; + // 只有 enabled 且有 stockCode 时才请求 + if (!enabled || !stockCode) return; const controller = new AbortController(); @@ -52,12 +66,17 @@ export const useManagementData = (stockCode?: string): UseManagementDataResult = setError("网络请求失败"); } finally { setLoading(false); + setHasLoaded(true); } }; loadData(); return () => controller.abort(); - }, [stockCode]); + }, [stockCode, enabled]); - return { management, loading, error }; + // 派生 loading 状态:enabled 但尚未完成首次加载时,视为 loading + // 这样可以在渲染时同步判断,避免 useEffect 异步导致的空状态闪烁 + const isLoading = loading || (enabled && !hasLoaded && !error); + + return { management, loading: isLoading, error }; }; diff --git a/src/views/Company/components/CompanyOverview/hooks/useShareholderData.ts b/src/views/Company/components/CompanyOverview/hooks/useShareholderData.ts index 17b65f1e..db312dda 100644 --- a/src/views/Company/components/CompanyOverview/hooks/useShareholderData.ts +++ b/src/views/Company/components/CompanyOverview/hooks/useShareholderData.ts @@ -11,6 +11,13 @@ interface ApiResponse { data: T; } +// 支持延迟加载的配置选项 +interface UseShareholderDataOptions { + stockCode?: string; + /** 是否启用数据加载,默认 true */ + enabled?: boolean; +} + interface UseShareholderDataResult { actualControl: ActualControl[]; concentration: Concentration[]; @@ -21,19 +28,25 @@ interface UseShareholderDataResult { } /** - * 股权结构数据 Hook - * @param stockCode - 股票代码 + * 股权结构数据 Hook(支持延迟加载) + * @param options - 配置选项 + * @param options.stockCode - 股票代码 + * @param options.enabled - 是否启用数据加载,默认 true */ -export const useShareholderData = (stockCode?: string): UseShareholderDataResult => { +export const useShareholderData = (options: UseShareholderDataOptions): UseShareholderDataResult => { + const { stockCode, enabled = true } = options; + const [actualControl, setActualControl] = useState([]); const [concentration, setConcentration] = useState([]); const [topShareholders, setTopShareholders] = useState([]); const [topCirculationShareholders, setTopCirculationShareholders] = useState([]); - const [loading, setLoading] = useState(false); + // 智能初始化 loading:当需要加载数据时,初始值为 true,避免首次渲染闪现空状态 + const [loading, setLoading] = useState(() => enabled && !!stockCode); const [error, setError] = useState(null); useEffect(() => { - if (!stockCode) return; + // 只有 enabled 且有 stockCode 时才请求 + if (!enabled || !stockCode) return; const controller = new AbortController(); @@ -69,7 +82,7 @@ export const useShareholderData = (stockCode?: string): UseShareholderDataResult loadData(); return () => controller.abort(); - }, [stockCode]); + }, [stockCode, enabled]); return { actualControl,