리액트 포탈은 리액트 공식 문서의 고급 안내서에 기제된 API 중 하나다.
Portal은 부모 컴포넌트의 DOM 계층 구조 바깥에 있는 DOM 노드로 자식을 렌더링하는 최고의 방법을 제공합니다.
https://ko.reactjs.org/docs/portals.html
처음 Dialog를 구현할 땐 root DOM 컨테이너 안에서 엘리먼트를 렌더링하려 했다. 여러 Dialog의 렌더링을 동시다발적으로 이루기 위해선 Dialog를 보여주고 숨겨주는 기능을 담당할 singleton Manager가 필요하다고 생각했고, 곧바로 이행했지만 좀처럼 만족스러운 코드와 결과가 나오지 못했다. libGDX처럼 리액트의 특수한 가상 돔 시스템이 없는 곳에선 괜찮은 구조였을진 몰라도 이 가상 돔의 환경에선 다르게 적용해야 하는 것이다.
Portal은 여러가지 강점을 지니는데, 일단
이 Manager 구조가 잘못되고, 작동하지 않는다는 말이 아니다. 다만 Portal을 적용하면 Manager가 불필요하기 때문에 그 가독성과 양적인 면에서 Portal가 우위를 점한다는 말이다.
Manager는 Dialog 컴포넌트들을 자식들로부터 받아 일괄적으로 랜더링하는 구조를 가지고 있다. 이러한 Manager는 Portal의 장점과 완벽히 상반된 모습을 띄고 있다.
마치 Portal는 이러한 Manager의 문제를 겪은 개발진들이 만들어낸 혜안과 같이 느껴졌다.
공식 문서에선 더 정확하고 확장적인 주제를 다루기 위해 CC를 통해 설명하지만 매우 단순하게 정리하자면 아래와 같다.
index.html
에서 root
엘리먼트와 같은 위치에 루트 엘리먼트를 만든다.ReactDOM.createPortal(children, container)
api 함수로 포탈을 생성하여 반환한다.modal-root
는 포탈을 생성하기 위한 좌표인 셈이다. ReactDOM는 react-dom
에서 default로 가져온다.실제로 테스트해보면 컴포넌트를 랜더링할 때마다 modal-root
의 자식 div가 갱신되는 모습을 볼 수 있다.