createPortal일부 하위 요소를 DOM의 다른 부분을 렌더링 할 수 있습니다.
<div>
<SomeComponent />
{createPortal(children, domNode, key?)}
</div>
<aside> 💡 포털은 DOM 노드의 물리적 배치만 변경합니다. 다른 모든 방법으로 포털에 렌더링하는 JSX는 이를 렌더링하는 React 구성 요소의 하위 노드 역할을 합니다. 예를 들어, 자식은 부모 트리에서 제공하는 컨텍스트에 액세스할 수 있으며, 이벤트는 React 트리에 따라 자식에서 부모로 버블링됩니다.
</aside>
포털을 사용 하면 구성 요소가 일부 하위 항목을 DOM의 다른 위치에 렌더링할 수 있습니다. 이를 통해 구성 요소의 일부가 어떤 컨테이너에 있든 "이스케이프"할 수 있습니다. 예를 들어 구성 요소는 페이지의 나머지 부분 위와 외부에 나타나는 모달 대화 상자나 도구 설명을 표시할 수 있습니다.
<aside>
💡 포털을 생성하려면 JSX 와 DOM 노드를 createPortal
사용하여 결과를 렌더링해야 합니다 .
</aside>
import { createPortal } from 'react-dom';
function MyComponent() {
return (
<div style={{ border: '2px solid black' }}>
<p>This child is placed in the parent div.</p>
{createPortal(
<p>This child is placed in the document body.</p>,
document.body
)}
</div>
);
}
포털이 없으면 두 번째 포털은 <p>
상위 내부에 배치되지만 <div>
포털은 포털을 다음으로 "순간 이동"했습니다 document.body
.
실제 활용
import React, { HTMLAttributes, useRef } from 'react';
import { createPortal } from 'react-dom';
import CloseBtn from 'assets/common/close_btn.png';
import { Modal as ModalProps } from 'features/modalSlice/types';
import * as S from './styles';
interface Props extends ModalProps, HTMLAttributes<HTMLDivElement> {}
const Modal: React.FC<Props> = ({
children,
size = `default`,
isShow = false,
title,
isXButton = true,
explanation,
headerComponentExtended,
footerComponent,
onClose,
}) => {
const modalRef = useRef<HTMLDivElement | null>(null);
return createPortal(
<S.ModalWrapper ref={modalRef}>
<S.ModalOverlay onClick={onClose} />
<S.ModalField modalSize={size} isShow={isShow}>
<S.ModalHeader>
{isXButton && (
<S.CloseBtn onClick={onClose}>
<img src={CloseBtn} alt="Close button" />
</S.CloseBtn>
)}
</S.ModalHeader>
<S.ModalBody>
{title && <S.ModalTit>{title}</S.ModalTit>}
<S.ModalExplanation>{explanation}</S.ModalExplanation>
{headerComponentExtended}
{children}
</S.ModalBody>
<S.ModalFooter>{footerComponent}</S.ModalFooter>
</S.ModalField>
</S.ModalWrapper>,
document.body,
);
};
export default Modal;