Portal이라고 이름이 정해있는 것은 아니지만,
저는 Portal이라는 이름을 사용하도록 하겠습니다.
지금부터 createPortal
를 이용하여
보통의 컴포넌트 DOM 계층에서는 접근 할 수 없는
<body>
태그의 자식으로 컴포넌트를 렌더링 할 수 있는 Portal 컴포넌트를 구현하려고 합니다.
React에서는 기본적으로 createPortal
이라는 API를 제공합니다.
createPortal
을 사용하면 일부 자식을 DOM의 다른 부분으로 렌더링 할 수 있습니다.
사용 예시
<div>
<SomeComponent />
{createPortal(children, domNode, key?)}
</div>
참고 링크 : createPortal
리액트 공식 문서를 참고하여
createPortal를 이용해 body에 자식 노드를 렌더링 하는 Portal 컴포넌트를 만들어 보았습니다.
Portal.tsx
import { type PropsWithChildren, useState } from 'react';
import { createPortal } from 'react-dom';
// react.createPortal을 이용해 document.body에 children을 렌더링합니다
const Portal = ({ children }: PropsWithChildren) => {
const [container, setContainer] = useState<Element | null>(null);
useEffect(() => {
if (document) {
setContainer(document.body);
}
}, []);
if (!container) return null;
return createPortal(children, container);
};
export default Portal;
useState
가 아닌useRef
상태를 관리 한다면 container가 바뀌어도 화면이 렌더링 되지 않아 문제가 발생할 수 있음
Portal 컴포넌트의 자식 노드를 넘기면
자식 노드는 body에 렌더링되게 됩니다.
return (
<Portal>{/*children*/}</Portal>
)