feat: 提交 Custom Hooks

This commit is contained in:
zdl
2025-10-30 13:04:42 +08:00
parent 3472d267af
commit 19a8866305
2 changed files with 266 additions and 0 deletions

View File

@@ -0,0 +1,135 @@
// src/views/Community/components/StockDetailPanel/hooks/useEventStocks.js
import { useSelector, useDispatch } from 'react-redux';
import { useEffect, useCallback, useMemo } from 'react';
import {
fetchEventStocks,
fetchStockQuotes,
fetchEventDetail,
fetchHistoricalEvents,
fetchChainAnalysis,
fetchExpectationScore
} from '../../../../../store/slices/stockSlice';
import { logger } from '../../../../../utils/logger';
/**
* 事件股票数据 Hook
* 封装事件相关的所有数据加载逻辑
*
* @param {string} eventId - 事件ID
* @param {string} eventTime - 事件时间
* @returns {Object} 事件数据和加载状态
*/
export const useEventStocks = (eventId, eventTime) => {
const dispatch = useDispatch();
// 从 Redux 获取数据
const stocks = useSelector(state =>
eventId ? (state.stock.eventStocksCache[eventId] || []) : []
);
const quotes = useSelector(state => state.stock.quotes);
const eventDetail = useSelector(state =>
eventId ? state.stock.eventDetailsCache[eventId] : null
);
const historicalEvents = useSelector(state =>
eventId ? (state.stock.historicalEventsCache[eventId] || []) : []
);
const chainAnalysis = useSelector(state =>
eventId ? state.stock.chainAnalysisCache[eventId] : null
);
const expectationScore = useSelector(state =>
eventId ? state.stock.expectationScores[eventId] : null
);
// 加载状态
const loading = useSelector(state => state.stock.loading);
// 加载所有数据
const loadAllData = useCallback(() => {
if (!eventId) {
logger.warn('useEventStocks', 'eventId 为空,跳过数据加载');
return;
}
logger.debug('useEventStocks', '开始加载事件数据', { eventId });
// 并发加载所有数据
dispatch(fetchEventStocks({ eventId }));
dispatch(fetchEventDetail({ eventId }));
dispatch(fetchHistoricalEvents({ eventId }));
dispatch(fetchChainAnalysis({ eventId }));
dispatch(fetchExpectationScore({ eventId }));
}, [dispatch, eventId]);
// 强制刷新所有数据
const refreshAllData = useCallback(() => {
if (!eventId) return;
logger.debug('useEventStocks', '强制刷新事件数据', { eventId });
dispatch(fetchEventStocks({ eventId, forceRefresh: true }));
dispatch(fetchEventDetail({ eventId, forceRefresh: true }));
dispatch(fetchHistoricalEvents({ eventId, forceRefresh: true }));
dispatch(fetchChainAnalysis({ eventId, forceRefresh: true }));
dispatch(fetchExpectationScore({ eventId }));
}, [dispatch, eventId]);
// 只刷新行情数据
const refreshQuotes = useCallback(() => {
if (stocks.length === 0) return;
const codes = stocks.map(s => s.stock_code);
logger.debug('useEventStocks', '刷新行情数据', {
stockCount: codes.length,
eventTime
});
dispatch(fetchStockQuotes({ codes, eventTime }));
}, [dispatch, stocks, eventTime]);
// 自动加载事件数据
useEffect(() => {
if (eventId) {
loadAllData();
}
}, [loadAllData]);
// 自动加载行情数据
useEffect(() => {
if (stocks.length > 0) {
refreshQuotes();
}
}, [stocks.length, eventId]); // 注意:这里不依赖 refreshQuotes避免重复请求
// 计算股票行情合并数据
const stocksWithQuotes = useMemo(() => {
return stocks.map(stock => ({
...stock,
quote: quotes[stock.stock_code] || null
}));
}, [stocks, quotes]);
return {
// 数据
stocks,
stocksWithQuotes,
quotes,
eventDetail,
historicalEvents,
chainAnalysis,
expectationScore,
// 加载状态
loading: {
stocks: loading.stocks,
quotes: loading.quotes,
eventDetail: loading.eventDetail,
historicalEvents: loading.historicalEvents,
chainAnalysis: loading.chainAnalysis
},
// 方法
loadAllData,
refreshAllData,
refreshQuotes
};
};