/** * 公司详情页面 * * 特性: * - 黑金主题设计 * - 懒加载 Tab 内容 * - memo 性能优化 * - axios 数据请求 */ import React, { memo, useCallback, useRef, useEffect, Suspense } from 'react'; import { useSearchParams } from 'react-router-dom'; import { Box, Spinner, Center } from '@chakra-ui/react'; import SubTabContainer from '@components/SubTabContainer'; import { useCompanyEvents } from './hooks/useCompanyEvents'; import { useCompanyData } from './hooks/useCompanyData'; import CompanyHeader from './components/CompanyHeader'; import { THEME, TAB_CONFIG } from './config'; // ============================================ // 加载状态组件 // ============================================ const TabLoadingFallback = memo(() => (
)); TabLoadingFallback.displayName = 'TabLoadingFallback'; // ============================================ // 主内容区组件 // ============================================ interface CompanyContentProps { stockCode: string; onTabChange: (index: number, tabKey: string) => void; } const CompanyContent = memo(({ stockCode, onTabChange }) => ( }> )); CompanyContent.displayName = 'CompanyContent'; // ============================================ // 主页面组件 // ============================================ const CompanyIndex: React.FC = () => { // URL 参数管理 const [searchParams, setSearchParams] = useSearchParams(); const stockCode = searchParams.get('scode') || '000001'; const prevStockCodeRef = useRef(stockCode); // 数据加载 Hook const { stockInfo, stockInfoLoading, isInWatchlist, watchlistLoading, toggleWatchlist, } = useCompanyData({ stockCode }); // 事件追踪 Hook const companyEvents = useCompanyEvents({ stockCode }) as { trackStockSearched: (newCode: string, oldCode: string | null) => void; trackTabChanged: (index: number, name: string, prevIndex: number) => void; trackWatchlistAdded: (code: string) => void; trackWatchlistRemoved: (code: string) => void; }; const { trackStockSearched, trackTabChanged, trackWatchlistAdded, trackWatchlistRemoved } = companyEvents; // 股票代码变化追踪 useEffect(() => { if (stockCode !== prevStockCodeRef.current) { trackStockSearched(stockCode, prevStockCodeRef.current); prevStockCodeRef.current = stockCode; } }, [stockCode, trackStockSearched]); // 处理股票切换 const handleStockChange = useCallback((newCode: string) => { if (newCode && newCode !== stockCode) { trackStockSearched(newCode, stockCode); setSearchParams({ scode: newCode }); } }, [stockCode, setSearchParams, trackStockSearched]); // 处理自选股切换(带追踪) const handleWatchlistToggle = useCallback(async () => { const wasInWatchlist = isInWatchlist; await toggleWatchlist(); // 追踪事件(根据操作前的状态判断) if (wasInWatchlist) { trackWatchlistRemoved(stockCode); } else { trackWatchlistAdded(stockCode); } }, [stockCode, isInWatchlist, toggleWatchlist, trackWatchlistAdded, trackWatchlistRemoved]); // 处理 Tab 切换 const handleTabChange = useCallback((index: number, tabKey: string) => { const tabName = TAB_CONFIG[index]?.name || tabKey; trackTabChanged(index, tabName, index); }, [trackTabChanged]); return ( {/* 顶部搜索栏 */} {/* 主内容区 */} ); }; export default memo(CompanyIndex);