Portal이란?
부모 컴포넌트의 DOM 계층 구조 바깥에 있는 DOM 노드로 자식을 렌더링을 해준다.
즉, 컴포넌트의 상하 관계 구조를 가지고 있는 DOM 상에서 자식 컴포넌트를 부모 컴포넌트의 외부에 있는 다른 컴포넌트에 전달할 수 있도록 해준다.
리액트 프로젝트에서 해당 컴포넌트를 어디에 렌더링 시킬지,
사전에 DOM을 선택하여 부모 컴포넌트 바깥에 렌더링해주는 기능이라고 생각하면 된다.
ReactDOM.createPortal(child, container)
ReactDom의 createPortal 메서드를 활용하여 포탈을 사용해 계층 밖으로 보낼 컴포넌트(child), 포탈로 이동할 목적지, DOM Element(container)를 인자로 넣어준다.
1. 모달이 렌더링할 위치 지정하기
index.html에서 최상단의 root와 형제 관계로 div Element를 넣어주도록 하자.
<body>
<div id="root"></div>
<div id="modal"></div>
</body>
2. ReactDOM.createPortal을 통해 Portal을 만들고 modalRoot로 portal될 수 있도록 한다.
export const Modal = ({ children }) => {
const modalRoot = document.getElementById('modal');
return ReactDOM.createPortal(
<StyledModalBackground>
<StyledModal>
{children}
</StyledModal>
</StyledModalBackground>,
modalRoot
);
};
3. 모달 로직이 동작하는 컴포넌트에 위 Modal 컴포넌트를 넣어주기만 하면 끝난다.
export const Profile = ({ name = '알 수 없음', userName = '' }) => {
const [isModalOpen, setIsModalOpen] = useState(false);
const navigate = useNavigate();
const handleOpenModal = () => setIsModalOpen(true);
const handleCloseModal = () => setIsModalOpen(false);
return (
<>
<ProfileWrapper onClick={handleOpenModal}>
<UserAvatar>
<img src={AvatarIcon} alt="avatar" />
</UserAvatar>
<UserInfoWrapper>
<NameWrapper>
<UserName>{name}</UserName>
</NameWrapper>
</UserInfoWrapper>
</ProfileWrapper>
<Modal isOpen={isModalOpen} onClose={handleCloseModal}>
<StyledModalTitle>내 정보</StyledModalTitle>
<Spacing size={16} direction="vertical" />
<StyledModalContent>{userName}</StyledModalContent>
<Spacing size={10} direction="vertical" />
<Button size="BIG" text="닫기" onClick={handleCloseModal} />
<Spacing size={8} direction="vertical" />
</Modal>
</>
);
};
728x90
'React' 카테고리의 다른 글
[React] useReducer에 대해 알아보자(with useState) (0) | 2025.01.19 |
---|---|
[React] Context API 개념 및 사용 방법 정리 (1) | 2024.11.26 |
[React] ReactNode / ReactElement / JSX.Element 의 차이 (0) | 2024.06.25 |
[React / Recoil] Link 태그와 a 태그의 차이(userState가 undefined가 생기는 문제) (0) | 2023.06.19 |