32 lines
855 B
TypeScript
32 lines
855 B
TypeScript
"use client";
|
|
|
|
import { useState, useEffect } from "react";
|
|
|
|
/**
|
|
* 모달 포탈 컨테이너 전역 레퍼런스.
|
|
* TabContent가 마운트 시 registerModalPortal(el)로 등록하고,
|
|
* 모달 컴포넌트들은 useModalPortal()로 컨테이너를 구독합니다.
|
|
* React 컴포넌트 트리 위치에 무관하게 동작합니다.
|
|
*/
|
|
let _container: HTMLElement | null = null;
|
|
const _subscribers = new Set<(el: HTMLElement | null) => void>();
|
|
|
|
export function registerModalPortal(el: HTMLElement | null) {
|
|
_container = el;
|
|
_subscribers.forEach((fn) => fn(el));
|
|
}
|
|
|
|
export function useModalPortal(): HTMLElement | null {
|
|
const [el, setEl] = useState<HTMLElement | null>(_container);
|
|
|
|
useEffect(() => {
|
|
setEl(_container);
|
|
_subscribers.add(setEl);
|
|
return () => {
|
|
_subscribers.delete(setEl);
|
|
};
|
|
}, []);
|
|
|
|
return el;
|
|
}
|