Portal은 부모 컴포넌트의 DOM 계층 구조 바깥에 있는 DOM 노드로 자식을 렌더링하는 최고의 방법을 제공한다.
리액트 포탈은 리액트 라이브러리에서 제공하는 기능 중 하나로, React 컴포넌트에서 DOM 트리 상에서의 위치를 변경할 수 있도록 해준다. 이 기능을 사용하면 컴포넌트의 렌더링 결과를 다른 DOM 노드로 이동시킬 수 있다.
< div id="root" >와 < div id="modal"> 은 형제 관계처럼 보이지만 실제로 modal은 root 안에서 보여지는 자식 컴포넌트이고,렌더링만 root의 바깥에서 이루어지고 있다.
ReactDOM.createPortal(child, container)
첫 번째 인자(child)는 엘리먼트, 문자열, 혹은 fragment와 같은 어떤 종류이든 렌더링할 수 있는 React 자식이고, 두 번째 인자(container)는 DOM 엘리먼트이다.
유연한 구성
: 리액트 포탈은 컴포넌트를 다른 DOM 위치로 이동시키기 때문에 UI 구성을 더욱 유연하게 할 수 있다.
예를 들어, Modal 창을 구현할 때 일반적으로는 모달 컴포넌트를 최상위 컴포넌트의 자식으로 추가해야 하는데 리액트 포탈을 사용하면 모달 컴포넌트를 원하는 위치로 이동시킬 수 있다. 복잡한 UI 구성을 쉽게 구현할 수 있다.
성능 최적화
: 리액트 포탈은 컴포넌트의 렌더링 결과를 다른 DOM 위치로 이동시키는 기능을 제공하므로, 컴포넌트의 렌더링이 최적화될 수 있다.
예를 들어, 상위 컴포넌트에서 자식 컴포넌트를 렌더링하면서 상태(State)를 변경하면, 해당 컴포넌트와 그 자식 컴포넌트가 모두 다시 렌더링된다.
하지만 리액트 포탈을 사용하면 해당 컴포넌트와 자식 컴포넌트 중에서 변경된 부분만 렌더링되므로, 불필요한 렌더링을 최소화할 수 있다.
모달(Modal): 모달은 부모 컴포넌트의 스타일링 속성에 제약을 받아 z-index 등으로 번거로운 후처리를 해줘야한다.하지만 포탈을 사용하면 독립적인 구조와 부모-자식 관계를 동시에 유지하면서, z-index 등 부모 컴포넌트의 제약에서 벗어날 수 있다.
포탈(Portal): 포탈은 일반적으로 다른 웹 페이지로 이동하는 링크를 클릭할 때, 새로운 브라우저 탭이나 창을 열어서 해당 페이지를 보여주는 기능을 말한다. 이 기능을 구현할때 포탈을 사용해보자
<body>
<div id="root"></div>
<div id="modal"></div> // 모달이 렌더링 될 위치
</body>
//modal div를 가져와 children으로 넣어주는 Portal역할을 할 Portal.js를 만들어준다.
import reactDom from "react-dom";
export const ModalPortal = ({ children }) => {
const el = document.getElementById("modal");
return reactDom.createPortal(children, el);
};
modal 컴포넌트 생성
modal을 사용할 컴포넌트에 Portal, Modal를 렌더링
//modal을 띄우려는 컴포넌트 파일
import ModalPortal from "../helpers/Portal";
import alertModal from "./defaultAlert1";
const Group = props => {
const [modalOn, setModalOn] = useState(false);
const handleModal = () => {
setModalOn(!modalOn);
};
return (
<>
<button onClick={handleModal} className="btn_registReq">alert창 띄우기</button>
<ModalPortal>
{modalOn && <Modal onClose={handleModal} />}
</ModalPortal>
</>
);
};
export default Group;