From d74162b7ced67c18f80571e0e0a6a9642470ab52 Mon Sep 17 00:00:00 2001 From: zdl <3489966805@qq.com> Date: Fri, 19 Dec 2025 18:58:53 +0800 Subject: [PATCH] =?UTF-8?q?fix(CompanyOverview):=20=E4=BF=AE=E5=A4=8D=20Re?= =?UTF-8?q?act=20Strict=20Mode=20=E4=B8=8B=E9=AA=A8=E6=9E=B6=E5=B1=8F?= =?UTF-8?q?=E9=97=AA=E7=8E=B0=E9=97=AE=E9=A2=98?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - 移除所有 hooks 中的 finally 块,避免请求取消时错误更新状态 - 添加 hasLoaded 状态追踪首次加载完成 - CanceledError 时直接返回,不更新任何状态 - 使用派生 isLoading 状态确保骨架屏正确显示 修复的 hooks: - useShareholderData.ts - useManagementData.ts - useAnnouncementsData.ts - useDisclosureData.ts - useBasicInfo.ts 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude --- .../hooks/useAnnouncementsData.ts | 21 +++++++++++++----- .../CompanyOverview/hooks/useBasicInfo.ts | 22 ++++++++++++++----- .../hooks/useDisclosureData.ts | 21 +++++++++++++----- .../hooks/useManagementData.ts | 16 +++++++++----- .../hooks/useShareholderData.ts | 22 ++++++++++++++----- 5 files changed, 75 insertions(+), 27 deletions(-) diff --git a/src/views/Company/components/CompanyOverview/hooks/useAnnouncementsData.ts b/src/views/Company/components/CompanyOverview/hooks/useAnnouncementsData.ts index 0b7a2ef2..e6ff2db8 100644 --- a/src/views/Company/components/CompanyOverview/hooks/useAnnouncementsData.ts +++ b/src/views/Company/components/CompanyOverview/hooks/useAnnouncementsData.ts @@ -37,12 +37,16 @@ export const useAnnouncementsData = (options: UseAnnouncementsDataOptions): UseA const { stockCode, enabled = true, refreshKey } = options; const [announcements, setAnnouncements] = useState([]); - const [loading, setLoading] = useState(false); + const [loading, setLoading] = useState(true); const [error, setError] = useState(null); + const [hasLoaded, setHasLoaded] = useState(false); useEffect(() => { // 只有 enabled 且有 stockCode 时才请求 - if (!enabled || !stockCode) return; + if (!enabled || !stockCode) { + setLoading(false); + return; + } const controller = new AbortController(); @@ -61,12 +65,17 @@ export const useAnnouncementsData = (options: UseAnnouncementsDataOptions): UseA } else { setError("加载公告数据失败"); } + setLoading(false); + setHasLoaded(true); } catch (err: any) { - if (err.name === "CanceledError") return; + // 请求被取消时,不更新任何状态 + if (err.name === "CanceledError") { + return; + } logger.error("useAnnouncementsData", "loadData", err, { stockCode }); setError("网络请求失败"); - } finally { setLoading(false); + setHasLoaded(true); } }; @@ -74,5 +83,7 @@ export const useAnnouncementsData = (options: UseAnnouncementsDataOptions): UseA return () => controller.abort(); }, [stockCode, enabled, refreshKey]); - return { announcements, loading, error }; + const isLoading = loading || (enabled && !hasLoaded && !error); + + return { announcements, loading: isLoading, error }; }; diff --git a/src/views/Company/components/CompanyOverview/hooks/useBasicInfo.ts b/src/views/Company/components/CompanyOverview/hooks/useBasicInfo.ts index b66a6db3..60ed2d3d 100644 --- a/src/views/Company/components/CompanyOverview/hooks/useBasicInfo.ts +++ b/src/views/Company/components/CompanyOverview/hooks/useBasicInfo.ts @@ -34,13 +34,16 @@ export const useBasicInfo = (options: UseBasicInfoOptions): UseBasicInfoResult = const { stockCode, enabled = true } = options; const [basicInfo, setBasicInfo] = useState(null); - // 智能初始化 loading:当需要加载数据时,初始值为 true,避免首次渲染闪现空状态 - const [loading, setLoading] = useState(() => enabled && !!stockCode); + const [loading, setLoading] = useState(true); const [error, setError] = useState(null); + const [hasLoaded, setHasLoaded] = useState(false); useEffect(() => { // 只有 enabled 且有 stockCode 时才请求 - if (!enabled || !stockCode) return; + if (!enabled || !stockCode) { + setLoading(false); + return; + } const controller = new AbortController(); @@ -59,12 +62,17 @@ export const useBasicInfo = (options: UseBasicInfoOptions): UseBasicInfoResult = } else { setError("加载基本信息失败"); } + setLoading(false); + setHasLoaded(true); } catch (err: any) { - if (err.name === "CanceledError") return; + // 请求被取消时,不更新任何状态 + if (err.name === "CanceledError") { + return; + } logger.error("useBasicInfo", "loadData", err, { stockCode }); setError("网络请求失败"); - } finally { setLoading(false); + setHasLoaded(true); } }; @@ -72,5 +80,7 @@ export const useBasicInfo = (options: UseBasicInfoOptions): UseBasicInfoResult = return () => controller.abort(); }, [stockCode, enabled]); - return { basicInfo, loading, error }; + const isLoading = loading || (enabled && !hasLoaded && !error); + + return { basicInfo, loading: isLoading, error }; }; diff --git a/src/views/Company/components/CompanyOverview/hooks/useDisclosureData.ts b/src/views/Company/components/CompanyOverview/hooks/useDisclosureData.ts index b506251a..38e4f229 100644 --- a/src/views/Company/components/CompanyOverview/hooks/useDisclosureData.ts +++ b/src/views/Company/components/CompanyOverview/hooks/useDisclosureData.ts @@ -34,12 +34,16 @@ export const useDisclosureData = (options: UseDisclosureDataOptions): UseDisclos const { stockCode, enabled = true } = options; const [disclosureSchedule, setDisclosureSchedule] = useState([]); - const [loading, setLoading] = useState(false); + const [loading, setLoading] = useState(true); const [error, setError] = useState(null); + const [hasLoaded, setHasLoaded] = useState(false); useEffect(() => { // 只有 enabled 且有 stockCode 时才请求 - if (!enabled || !stockCode) return; + if (!enabled || !stockCode) { + setLoading(false); + return; + } const controller = new AbortController(); @@ -58,12 +62,17 @@ export const useDisclosureData = (options: UseDisclosureDataOptions): UseDisclos } else { setError("加载披露日程数据失败"); } + setLoading(false); + setHasLoaded(true); } catch (err: any) { - if (err.name === "CanceledError") return; + // 请求被取消时,不更新任何状态 + if (err.name === "CanceledError") { + return; + } logger.error("useDisclosureData", "loadData", err, { stockCode }); setError("网络请求失败"); - } finally { setLoading(false); + setHasLoaded(true); } }; @@ -71,5 +80,7 @@ export const useDisclosureData = (options: UseDisclosureDataOptions): UseDisclos return () => controller.abort(); }, [stockCode, enabled]); - return { disclosureSchedule, loading, error }; + const isLoading = loading || (enabled && !hasLoaded && !error); + + return { disclosureSchedule, loading: isLoading, error }; }; diff --git a/src/views/Company/components/CompanyOverview/hooks/useManagementData.ts b/src/views/Company/components/CompanyOverview/hooks/useManagementData.ts index 80ca61fd..62590e77 100644 --- a/src/views/Company/components/CompanyOverview/hooks/useManagementData.ts +++ b/src/views/Company/components/CompanyOverview/hooks/useManagementData.ts @@ -34,14 +34,16 @@ export const useManagementData = (options: UseManagementDataOptions): UseManagem const { stockCode, enabled = true } = options; const [management, setManagement] = useState([]); - const [loading, setLoading] = useState(() => enabled && !!stockCode); + const [loading, setLoading] = useState(true); const [error, setError] = useState(null); - // 记录是否已完成首次加载,用于派生 loading 状态 const [hasLoaded, setHasLoaded] = useState(false); useEffect(() => { // 只有 enabled 且有 stockCode 时才请求 - if (!enabled || !stockCode) return; + if (!enabled || !stockCode) { + setLoading(false); + return; + } const controller = new AbortController(); @@ -60,11 +62,15 @@ export const useManagementData = (options: UseManagementDataOptions): UseManagem } else { setError("加载管理团队数据失败"); } + setLoading(false); + setHasLoaded(true); } catch (err: any) { - if (err.name === "CanceledError") return; + // 请求被取消时,不更新任何状态 + if (err.name === "CanceledError") { + return; + } logger.error("useManagementData", "loadData", err, { stockCode }); setError("网络请求失败"); - } finally { setLoading(false); setHasLoaded(true); } diff --git a/src/views/Company/components/CompanyOverview/hooks/useShareholderData.ts b/src/views/Company/components/CompanyOverview/hooks/useShareholderData.ts index db312dda..6c47b62d 100644 --- a/src/views/Company/components/CompanyOverview/hooks/useShareholderData.ts +++ b/src/views/Company/components/CompanyOverview/hooks/useShareholderData.ts @@ -40,13 +40,16 @@ export const useShareholderData = (options: UseShareholderDataOptions): UseShare const [concentration, setConcentration] = useState([]); const [topShareholders, setTopShareholders] = useState([]); const [topCirculationShareholders, setTopCirculationShareholders] = useState([]); - // 智能初始化 loading:当需要加载数据时,初始值为 true,避免首次渲染闪现空状态 - const [loading, setLoading] = useState(() => enabled && !!stockCode); + const [loading, setLoading] = useState(true); const [error, setError] = useState(null); + const [hasLoaded, setHasLoaded] = useState(false); useEffect(() => { // 只有 enabled 且有 stockCode 时才请求 - if (!enabled || !stockCode) return; + if (!enabled || !stockCode) { + setLoading(false); + return; + } const controller = new AbortController(); @@ -71,12 +74,17 @@ export const useShareholderData = (options: UseShareholderDataOptions): UseShare if (concentrationRes.success) setConcentration(concentrationRes.data); if (shareholdersRes.success) setTopShareholders(shareholdersRes.data); if (circulationRes.success) setTopCirculationShareholders(circulationRes.data); + setLoading(false); + setHasLoaded(true); } catch (err: any) { - if (err.name === "CanceledError") return; + // 请求被取消时,不更新任何状态 + if (err.name === "CanceledError") { + return; + } logger.error("useShareholderData", "loadData", err, { stockCode }); setError("加载股权结构数据失败"); - } finally { setLoading(false); + setHasLoaded(true); } }; @@ -84,12 +92,14 @@ export const useShareholderData = (options: UseShareholderDataOptions): UseShare return () => controller.abort(); }, [stockCode, enabled]); + const isLoading = loading || (enabled && !hasLoaded && !error); + return { actualControl, concentration, topShareholders, topCirculationShareholders, - loading, + loading: isLoading, error, }; };