metms_fe/src/components/customs/custom-portal.tsx
2026-05-23 09:48:07 +07:00

53 lines
1016 B
TypeScript

"use client";
import { ReactNode, useLayoutEffect, useMemo } from "react";
import { createPortal } from "react-dom";
interface Props {
children: ReactNode;
className?: string;
containerId?: string;
}
export default function CustomPortal({
children,
className,
containerId,
}: Props) {
// ✅ tạo element 1 lần duy nhất
const element = useMemo(() => {
if (typeof window === "undefined") return null;
const el = document.createElement("div");
if (className) {
el.className = className;
}
return el;
}, [className]);
useLayoutEffect(() => {
if (!element) return;
const parent = containerId
? document.getElementById(containerId)
: document.body;
if (!parent) return;
parent.appendChild(element);
return () => {
parent.removeChild(element);
};
}, [element, containerId]);
// ✅ không dùng ref.current
// ✅ không dùng setState
if (!element) return null;
return createPortal(children, element);
}