- 移除所有 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>
87 lines
2.3 KiB
TypeScript
87 lines
2.3 KiB
TypeScript
// 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 };
|
||
};
|