알림목록 지표로딩 오류
This commit is contained in:
@@ -2,7 +2,7 @@
|
|||||||
* 매매 시그널 알림 목록 행 — 종목×전략 실시간 신호 스냅샷 (가상매매 카드 요약형과 동일 소스)
|
* 매매 시그널 알림 목록 행 — 종목×전략 실시간 신호 스냅샷 (가상매매 카드 요약형과 동일 소스)
|
||||||
*/
|
*/
|
||||||
import { useCallback, useEffect, useRef, useState } from 'react';
|
import { useCallback, useEffect, useRef, useState } from 'react';
|
||||||
import type { StrategyDto } from '../utils/backendApi';
|
import { isStrategyMissingOnServer, loadStrategy, type StrategyDto } from '../utils/backendApi';
|
||||||
import {
|
import {
|
||||||
fetchLiveSnapshot,
|
fetchLiveSnapshot,
|
||||||
type VirtualIndicatorSnapshot,
|
type VirtualIndicatorSnapshot,
|
||||||
@@ -19,6 +19,8 @@ export function useTradeNotificationSignalSnapshot(
|
|||||||
const [loading, setLoading] = useState(false);
|
const [loading, setLoading] = useState(false);
|
||||||
const emptyRetryRef = useRef(0);
|
const emptyRetryRef = useRef(0);
|
||||||
const genRef = useRef(0);
|
const genRef = useRef(0);
|
||||||
|
/** strategy prop 이 undefined 일 때 직접 로드한 전략 캐시 */
|
||||||
|
const fallbackStrategyRef = useRef<StrategyDto | null>(null);
|
||||||
|
|
||||||
const refresh = useCallback(async () => {
|
const refresh = useCallback(async () => {
|
||||||
if (!enabled || strategyId == null) {
|
if (!enabled || strategyId == null) {
|
||||||
@@ -29,8 +31,27 @@ export function useTradeNotificationSignalSnapshot(
|
|||||||
|
|
||||||
const gen = ++genRef.current;
|
const gen = ++genRef.current;
|
||||||
setLoading(true);
|
setLoading(true);
|
||||||
|
|
||||||
|
// strategy prop 이 undefined 면 내부에서 직접 로드해 baseRows 를 확보한다.
|
||||||
|
// 이렇게 하면 strategy 가 늦게 주입되어도 조건 목록이 즉시 표시된다.
|
||||||
|
let effectiveStrategy = strategy;
|
||||||
|
if (!effectiveStrategy) {
|
||||||
|
if (fallbackStrategyRef.current) {
|
||||||
|
effectiveStrategy = fallbackStrategyRef.current;
|
||||||
|
} else if (!isStrategyMissingOnServer(strategyId)) {
|
||||||
|
try {
|
||||||
|
const loaded = await loadStrategy(strategyId);
|
||||||
|
if (loaded) {
|
||||||
|
fallbackStrategyRef.current = loaded;
|
||||||
|
effectiveStrategy = loaded;
|
||||||
|
}
|
||||||
|
} catch { /* ignore */ }
|
||||||
|
if (gen !== genRef.current) return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
const pinFirst = emptyRetryRef.current === 0;
|
const pinFirst = emptyRetryRef.current === 0;
|
||||||
const snap = await fetchLiveSnapshot(market, strategyId, strategy, pinFirst);
|
const snap = await fetchLiveSnapshot(market, strategyId, effectiveStrategy, pinFirst);
|
||||||
if (gen !== genRef.current) return;
|
if (gen !== genRef.current) return;
|
||||||
|
|
||||||
if (snap && snap.rows.length > 0) {
|
if (snap && snap.rows.length > 0) {
|
||||||
@@ -40,14 +61,7 @@ export function useTradeNotificationSignalSnapshot(
|
|||||||
}
|
}
|
||||||
|
|
||||||
setSnapshot(snap ?? undefined);
|
setSnapshot(snap ?? undefined);
|
||||||
|
|
||||||
// strategy 가 아직 로드되지 않았고 데이터도 없으면 loading 유지:
|
|
||||||
// strategy 가 로드되면 refresh 가 갱신되어 재시도하며, 그때 조건이 표시된다.
|
|
||||||
if (!snap && strategy === undefined) {
|
|
||||||
setLoading(true);
|
|
||||||
} else {
|
|
||||||
setLoading(false);
|
setLoading(false);
|
||||||
}
|
|
||||||
}, [market, strategyId, strategy, enabled]);
|
}, [market, strategyId, strategy, enabled]);
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
@@ -58,6 +72,7 @@ export function useTradeNotificationSignalSnapshot(
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
emptyRetryRef.current = 0;
|
emptyRetryRef.current = 0;
|
||||||
|
fallbackStrategyRef.current = null; // strategy prop 변경 시 캐시 초기화
|
||||||
setLoading(true); // 활성화 즉시 로딩 표시
|
setLoading(true); // 활성화 즉시 로딩 표시
|
||||||
void refresh();
|
void refresh();
|
||||||
const id = window.setInterval(() => void refresh(), pollMs);
|
const id = window.setInterval(() => void refresh(), pollMs);
|
||||||
|
|||||||
Reference in New Issue
Block a user