- StockQuoteCard: 添加 memo 包装减少重渲染 - Company/index: componentProps 使用 useMemo 缓存 - useCompanyEvents: 页面浏览事件只触发一次,避免重复追踪 - useCompanyData: 自选股状态改用单股票查询接口,减少数据传输 - CompanyHeader: inputCode 状态下移到 SearchActions,减少父组件重渲染 - CompanyHeader: 移除重复环境光效果,由全局 AmbientGlow 统一处理 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com>
108 lines
3.1 KiB
JavaScript
108 lines
3.1 KiB
JavaScript
// src/views/Company/hooks/useCompanyEvents.js
|
|
// 公司详情页面事件追踪 Hook
|
|
|
|
import { useCallback, useEffect, useRef } from 'react';
|
|
import { usePostHogTrack } from '../../../hooks/usePostHogRedux';
|
|
import { RETENTION_EVENTS } from '../../../lib/constants';
|
|
import { logger } from '../../../utils/logger';
|
|
|
|
/**
|
|
* 公司详情页面事件追踪 Hook
|
|
* @param {Object} options - 配置选项
|
|
* @param {string} options.stockCode - 当前股票代码
|
|
* @returns {Object} 事件追踪处理函数集合
|
|
*/
|
|
export const useCompanyEvents = ({ stockCode } = {}) => {
|
|
const { track } = usePostHogTrack();
|
|
const hasTrackedPageView = useRef(false);
|
|
|
|
// 🎯 页面浏览事件 - 仅页面首次加载时触发一次
|
|
useEffect(() => {
|
|
if (hasTrackedPageView.current) return;
|
|
hasTrackedPageView.current = true;
|
|
|
|
track(RETENTION_EVENTS.COMPANY_PAGE_VIEWED, {
|
|
timestamp: new Date().toISOString(),
|
|
stock_code: stockCode || null,
|
|
});
|
|
logger.debug('useCompanyEvents', '📊 Company Page Viewed', { stockCode });
|
|
}, [track, stockCode]);
|
|
|
|
/**
|
|
* 追踪股票搜索/切换
|
|
* @param {string} newStockCode - 新的股票代码
|
|
* @param {string} previousStockCode - 之前的股票代码
|
|
*/
|
|
const trackStockSearched = useCallback((newStockCode, previousStockCode = null) => {
|
|
if (!newStockCode) return;
|
|
|
|
track(RETENTION_EVENTS.STOCK_SEARCHED, {
|
|
query: newStockCode,
|
|
stock_code: newStockCode,
|
|
previous_stock_code: previousStockCode,
|
|
context: 'company_page',
|
|
});
|
|
|
|
logger.debug('useCompanyEvents', '🔍 Stock Searched', {
|
|
newStockCode,
|
|
previousStockCode,
|
|
});
|
|
}, [track]);
|
|
|
|
/**
|
|
* 追踪 Tab 切换
|
|
* @param {number} tabIndex - Tab 索引 (0: 公司概览, 1: 股票行情, 2: 财务全景, 3: 盈利预测)
|
|
* @param {string} tabName - Tab 名称
|
|
* @param {number} previousTabIndex - 之前的 Tab 索引
|
|
*/
|
|
const trackTabChanged = useCallback((tabIndex, tabName, previousTabIndex = null) => {
|
|
track(RETENTION_EVENTS.TAB_CHANGED, {
|
|
tab_index: tabIndex,
|
|
tab_name: tabName,
|
|
previous_tab_index: previousTabIndex,
|
|
stock_code: stockCode,
|
|
context: 'company_page',
|
|
});
|
|
|
|
logger.debug('useCompanyEvents', '🔄 Tab Changed', {
|
|
tabIndex,
|
|
tabName,
|
|
previousTabIndex,
|
|
stockCode,
|
|
});
|
|
}, [track, stockCode]);
|
|
|
|
/**
|
|
* 追踪加入自选股
|
|
* @param {string} stock_code - 股票代码
|
|
*/
|
|
const trackWatchlistAdded = useCallback((stock_code) => {
|
|
track(RETENTION_EVENTS.WATCHLIST_ADDED, {
|
|
stock_code,
|
|
source: 'company_page',
|
|
});
|
|
|
|
logger.debug('useCompanyEvents', '⭐ Watchlist Added', { stock_code });
|
|
}, [track]);
|
|
|
|
/**
|
|
* 追踪移除自选股
|
|
* @param {string} stock_code - 股票代码
|
|
*/
|
|
const trackWatchlistRemoved = useCallback((stock_code) => {
|
|
track(RETENTION_EVENTS.WATCHLIST_REMOVED, {
|
|
stock_code,
|
|
source: 'company_page',
|
|
});
|
|
|
|
logger.debug('useCompanyEvents', '❌ Watchlist Removed', { stock_code });
|
|
}, [track]);
|
|
|
|
return {
|
|
trackStockSearched,
|
|
trackTabChanged,
|
|
trackWatchlistAdded,
|
|
trackWatchlistRemoved,
|
|
};
|
|
};
|