전략편집기 화면접속 시 에러 수정
This commit is contained in:
@@ -36,6 +36,8 @@ export interface MarketInfo {
|
||||
}
|
||||
|
||||
export interface UseMarketTickerOptions {
|
||||
/** false — REST·WS 중지(전략편집기 등), 캐시된 tickers 유지 */
|
||||
enabled?: boolean;
|
||||
/** 우선 종목만 먼저 로드 (기본: 마켓 패널 닫힘) */
|
||||
lite?: boolean;
|
||||
priorityMarkets?: string[];
|
||||
@@ -147,6 +149,7 @@ function subscribeTickerWs(
|
||||
}
|
||||
|
||||
export function useMarketTicker(opts: UseMarketTickerOptions = {}) {
|
||||
const enabled = opts.enabled ?? true;
|
||||
const loadFull = opts.loadFull ?? false;
|
||||
const isMobileLite = opts.lite ?? false;
|
||||
const priorityList = mergePriorityMarkets(opts.getPriorityMarkets?.() ?? opts.priorityMarkets);
|
||||
@@ -209,12 +212,14 @@ export function useMarketTicker(opts: UseMarketTickerOptions = {}) {
|
||||
}, [applyRawList, clearPoll, isMobileLite]);
|
||||
|
||||
const loadTickersFor = useCallback(async (markets: string[]) => {
|
||||
if (!enabled) return [];
|
||||
const rawList = await fetchTickersThrottled(markets);
|
||||
if (mountedRef.current && rawList.length > 0) applyRawList(rawList);
|
||||
return rawList;
|
||||
}, [applyRawList]);
|
||||
}, [applyRawList, enabled]);
|
||||
|
||||
const runFullTickerLoad = useCallback(async () => {
|
||||
if (!enabled) return;
|
||||
const all = marketListRef.current;
|
||||
if (all.length === 0 || fullLoadedRef.current) return;
|
||||
|
||||
@@ -231,19 +236,57 @@ export function useMarketTicker(opts: UseMarketTickerOptions = {}) {
|
||||
fullLoadedRef.current = true;
|
||||
attachWs(wsTickerMarkets(all, priorityList));
|
||||
startPoll(all);
|
||||
}, [isMobileLite, loadTickersFor, attachWs, startPoll, priorityList]);
|
||||
}, [enabled, isMobileLite, loadTickersFor, attachWs, startPoll, priorityList]);
|
||||
|
||||
// 1) 마켓 목록 + 우선 종목 ticker (마운트 1회)
|
||||
const pauseFeed = useCallback(() => {
|
||||
destroyWsRef.current?.();
|
||||
destroyWsRef.current = null;
|
||||
clearPoll();
|
||||
}, [clearPoll]);
|
||||
|
||||
const resumeFeed = useCallback(() => {
|
||||
const all = marketListRef.current;
|
||||
if (all.length === 0) return;
|
||||
attachWs(wsTickerMarkets(all, priorityList));
|
||||
if (loadFull && fullLoadedRef.current && !isMobileLite) {
|
||||
startPoll(all);
|
||||
}
|
||||
}, [attachWs, priorityList, loadFull, isMobileLite, startPoll]);
|
||||
|
||||
// 마운트 생명주기
|
||||
useEffect(() => {
|
||||
mountedRef.current = true;
|
||||
fullLoadedRef.current = false;
|
||||
initDoneRef.current = false;
|
||||
return () => {
|
||||
mountedRef.current = false;
|
||||
pauseFeed();
|
||||
};
|
||||
}, [pauseFeed]);
|
||||
|
||||
const enabledRef = useRef(enabled);
|
||||
enabledRef.current = enabled;
|
||||
const priorityListRef = useRef(priorityList);
|
||||
priorityListRef.current = priorityList;
|
||||
const loadFullRef = useRef(loadFull);
|
||||
loadFullRef.current = loadFull;
|
||||
|
||||
// enabled: 비차트 화면(전략편집기 등)에서 REST·WS 중지
|
||||
useEffect(() => {
|
||||
if (!enabled) {
|
||||
pauseFeed();
|
||||
if (initDoneRef.current) setLoading(false);
|
||||
return;
|
||||
}
|
||||
if (initDoneRef.current) {
|
||||
resumeFeed();
|
||||
return;
|
||||
}
|
||||
|
||||
let cancelled = false;
|
||||
(async () => {
|
||||
let infos: MarketInfo[] = [];
|
||||
try { infos = await fetchAllMarkets(); }
|
||||
catch { /* ignore */ }
|
||||
if (!mountedRef.current) return;
|
||||
if (cancelled || !mountedRef.current || !enabledRef.current) return;
|
||||
|
||||
infos.forEach(m => marketInfoMapRef.current.set(m.market, m));
|
||||
setMarketInfos(infos);
|
||||
@@ -252,40 +295,40 @@ export function useMarketTicker(opts: UseMarketTickerOptions = {}) {
|
||||
if (!allMarkets.includes('KRW-USDT')) allMarkets.push('KRW-USDT');
|
||||
marketListRef.current = allMarkets;
|
||||
|
||||
await loadTickersFor(priorityList);
|
||||
if (!mountedRef.current) return;
|
||||
const pri = mergePriorityMarkets(
|
||||
opts.getPriorityMarkets?.() ?? opts.priorityMarkets,
|
||||
);
|
||||
if (!enabledRef.current) return;
|
||||
const rawList = await fetchTickersThrottled(pri);
|
||||
if (cancelled || !mountedRef.current || !enabledRef.current) return;
|
||||
if (rawList.length > 0) applyRawList(rawList);
|
||||
|
||||
setLoading(false);
|
||||
initDoneRef.current = true;
|
||||
attachWs(wsTickerMarkets(allMarkets, priorityList));
|
||||
attachWs(wsTickerMarkets(allMarkets, pri));
|
||||
|
||||
if (loadFull && !isMobileLite) {
|
||||
if (loadFullRef.current && !isMobileLite) {
|
||||
setTimeout(() => { void runFullTickerLoad(); }, FULL_LOAD_DEFER_MS);
|
||||
}
|
||||
})();
|
||||
|
||||
return () => {
|
||||
mountedRef.current = false;
|
||||
destroyWsRef.current?.();
|
||||
destroyWsRef.current = null;
|
||||
clearPoll();
|
||||
};
|
||||
// eslint-disable-next-line react-hooks/exhaustive-deps -- init only
|
||||
}, []);
|
||||
return () => { cancelled = true; };
|
||||
// eslint-disable-next-line react-hooks/exhaustive-deps -- enabled 토글·최초 1회만
|
||||
}, [enabled]);
|
||||
|
||||
// 2) 마켓 패널 열림 → 전 종목 (모바일: 백엔드 1회, PC: 지연 후 일괄)
|
||||
// 마켓 패널 열림 → 전 종목
|
||||
useEffect(() => {
|
||||
if (!loadFull || !initDoneRef.current) return;
|
||||
if (!enabled || !loadFull || !initDoneRef.current) return;
|
||||
if (fullLoadedRef.current) return;
|
||||
|
||||
const delay = isMobileLite ? 300 : FULL_LOAD_DEFER_MS;
|
||||
const t = setTimeout(() => { void runFullTickerLoad(); }, delay);
|
||||
return () => clearTimeout(t);
|
||||
}, [isMobileLite, loadFull, runFullTickerLoad]);
|
||||
}, [enabled, isMobileLite, loadFull, runFullTickerLoad]);
|
||||
|
||||
// 3) 우선 종목 변경 — 디바운스(메뉴·심볼 전환 시 REST 폭주 방지)
|
||||
// 우선 종목 변경
|
||||
useEffect(() => {
|
||||
if (!initDoneRef.current) return;
|
||||
if (!enabled || !initDoneRef.current) return;
|
||||
const t = setTimeout(() => {
|
||||
if (!mountedRef.current) return;
|
||||
if (!fullLoadedRef.current) void loadTickersFor(priorityList);
|
||||
@@ -293,7 +336,7 @@ export function useMarketTicker(opts: UseMarketTickerOptions = {}) {
|
||||
if (all.length > 0) attachWs(wsTickerMarkets(all, priorityList));
|
||||
}, PRIORITY_DEBOUNCE_MS);
|
||||
return () => clearTimeout(t);
|
||||
}, [priorityKey, loadTickersFor, attachWs, priorityList]);
|
||||
}, [enabled, priorityKey, loadTickersFor, attachWs, priorityList]);
|
||||
|
||||
return { tickers, marketInfos, loading, usdRate };
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user