54 lines
1.6 KiB
TypeScript
54 lines
1.6 KiB
TypeScript
import { useEffect, useRef } from "react";
|
|
import { useKisWebSocketStore } from "@/features/kis-realtime/stores/kisWebSocketStore";
|
|
|
|
/**
|
|
* @file features/kis-realtime/hooks/useKisWebSocket.ts
|
|
* @description KIS 실시간 데이터를 구독하기 위한 통합 훅입니다.
|
|
* 컴포넌트 마운트/언마운트 시 자동으로 구독 및 해제를 처리합니다.
|
|
*/
|
|
|
|
type RealtimeCallback = (data: string) => void;
|
|
|
|
interface UseKisWebSocketParams {
|
|
symbol?: string; // 종목코드 (없으면 구독 안 함)
|
|
trId?: string; // 거래 ID (예: H0STCNT0)
|
|
onMessage?: RealtimeCallback; // 데이터 수신 콜백
|
|
enabled?: boolean; // 구독 활성화 여부
|
|
}
|
|
|
|
export function useKisWebSocket({
|
|
symbol,
|
|
trId,
|
|
onMessage,
|
|
enabled = true,
|
|
}: UseKisWebSocketParams) {
|
|
const subscribeRef = useRef(useKisWebSocketStore.getState().subscribe);
|
|
const connectRef = useRef(useKisWebSocketStore.getState().connect);
|
|
const { isConnected } = useKisWebSocketStore();
|
|
const callbackRef = useRef(onMessage);
|
|
|
|
// 콜백 함수가 바뀌어도 재구독하지 않도록 ref 사용
|
|
useEffect(() => {
|
|
callbackRef.current = onMessage;
|
|
}, [onMessage]);
|
|
|
|
useEffect(() => {
|
|
if (!enabled || !symbol || !trId) return;
|
|
|
|
// 연결 시도 (이미 연결 중이면 스토어에서 무시됨)
|
|
connectRef.current();
|
|
|
|
// 구독 요청
|
|
const unsubscribe = subscribeRef.current(trId, symbol, (data) => {
|
|
callbackRef.current?.(data);
|
|
});
|
|
|
|
// 언마운트 시 구독 해제
|
|
return () => {
|
|
unsubscribe();
|
|
};
|
|
}, [symbol, trId, enabled]);
|
|
|
|
return { isConnected };
|
|
}
|