Files
vf_react/src/views/Company/components/CompanyOverview/hooks/useBasicInfo.ts
zdl d74162b7ce fix(CompanyOverview): 修复 React Strict Mode 下骨架屏闪现问题
- 移除所有 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 <noreply@anthropic.com>
2025-12-19 18:58:53 +08:00

87 lines
2.3 KiB
TypeScript
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

// src/views/Company/components/CompanyOverview/hooks/useBasicInfo.ts
// 公司基本信息 Hook - 用于 CompanyHeaderCard
import { useState, useEffect } from "react";
import { logger } from "@utils/logger";
import axios from "@utils/axiosConfig";
import type { BasicInfo } from "../types";
interface ApiResponse<T> {
success: boolean;
data: T;
}
// 支持延迟加载的配置选项
interface UseBasicInfoOptions {
stockCode?: string;
/** 是否启用数据加载,默认 true */
enabled?: boolean;
}
interface UseBasicInfoResult {
basicInfo: BasicInfo | null;
loading: boolean;
error: string | null;
}
/**
* 公司基本信息 Hook支持延迟加载
* @param options - 配置选项
* @param options.stockCode - 股票代码
* @param options.enabled - 是否启用数据加载,默认 true
*/
export const useBasicInfo = (options: UseBasicInfoOptions): UseBasicInfoResult => {
const { stockCode, enabled = true } = options;
const [basicInfo, setBasicInfo] = useState<BasicInfo | null>(null);
const [loading, setLoading] = useState(true);
const [error, setError] = useState<string | null>(null);
const [hasLoaded, setHasLoaded] = useState(false);
useEffect(() => {
// 只有 enabled 且有 stockCode 时才请求
if (!enabled || !stockCode) {
setLoading(false);
return;
}
const controller = new AbortController();
const loadData = async () => {
setLoading(true);
setError(null);
try {
const { data: result } = await axios.get<ApiResponse<BasicInfo>>(
`/api/stock/${stockCode}/basic-info`,
{ signal: controller.signal }
);
if (result.success) {
setBasicInfo(result.data);
} else {
setError("加载基本信息失败");
}
setLoading(false);
setHasLoaded(true);
} catch (err: any) {
// 请求被取消时,不更新任何状态
if (err.name === "CanceledError") {
return;
}
logger.error("useBasicInfo", "loadData", err, { stockCode });
setError("网络请求失败");
setLoading(false);
setHasLoaded(true);
}
};
loadData();
return () => controller.abort();
}, [stockCode, enabled]);
const isLoading = loading || (enabled && !hasLoaded && !error);
return { basicInfo, loading: isLoading, error };
};