new TIL. React Portals & Modal

유자탱자🍋·2021년 4월 16일
0
post-thumbnail

모달 창은 사용자에게 특정 내용을 강조하여 전달하고자 할 때 사용한다. 모달 창에 대한 주목도를 높이기 위해 일반적으로 배경을 어두운 색상으로 두어 대비를 준다.

그런데 위 이미지와 같이 다른 컨텐츠들이 모달 창보다 높은 z-index를 가진다면? 좋은 모달 창이라고 할 수 없을 것이다.

해결 방법으로 React Portals를 알아보고자 한다!


📌 Portals 이란?

React portal is just a way to render components outside of the normal DOM hierarchy that is defined by the component tree.

부모 컴포넌트 밖에서 랜더링되기 때문에 부모의 스타일을 상속받지도 않고, 모달 창과 같이 가장 위에 있는 레이어에서 구현되어야 할 경우 z-index을 설정하기도 편리하다.

" portals의 일반적인 사용 사례는 부모 컴포넌트가 overflow: hidden 이나 z-index 스타일을 가지지만, 자식이 컨테이너에서 시각적으로 “이탈해야 하는” 경우입니다. "

➕ 부모 컴포넌트와 같은 DOM 트리에 있지 않기 때문에 불필요한 랜더링이 발생하지 않는다.

" React portal is an incredibly useful tool since it allows rendering of components outside the normal DOM hierarchy without breaking event propagation of the component hierarchy. This is incredibly useful when rendering components such as modals, tooltips, popup messages, and so much more. "

( 위 코드처럼 other content의 z-index가 2라면 Modal 컴포넌트의 z-index가 아무리 높아도 부모의 z-index가 1이기 때문에 처음 보았던 이미지처럼 모달 창이 열렸을 때도 other content가 진하게 보인다🥲 )


📌 그럼 어떻게 사용하면 될까?

React에서는 가상 DOM이 들어갈 껍데기의 역할을 하는 index.html이 있다. 거기에는 <div id="root"></div>가 있고, 그것이 index.js를 통해 App.js로 연결되어 있다.

id가 root라는 DOM 외부에서 랜더링을 하기 위해서는 ReactDOM.createPortal(child, container)을 사용하면 된다.

여기서 container는 UI를 랜더링 시키고자 하는 DOM을 의미한다.

  <body>
    <noscript>You need to enable JavaScript to run this app.</noscript>
    <div id="root"></div>
    <div id="portal"></div>
  </body>

그러면 개발자 도구에서 전체 화면과 모달 창 컴포넌트 위치가 분리된 것을 볼 수 있다.


📌 모달 창 구현 로직

부모 컴포넌트에서 모달 창을 열고 닫는 상태를 관리하는 isOpen state를 만들어주고, open props를 넘겨준다. onClick 이벤트가 실행될 경우, setInOpen 함수를 통해 state isOpen을 true 값으로 바꿔준다.

모달 창이 닫힐 때는 반대로 setInOpen 함수를 통해 state isOpen을 false로 바꿔주는데, 자식 컴포넌트인 Modal에 Close Modal 버튼이 있기 때문에 props로 넘겨주어야 한다.

따라서, state 값을 false로 변경해주는 함수를 onClose라는 props로 넘겨주고, onClick={onClose}를 통해 받아주면 된다!



참고)
-Learn React Portal In 12 Minutes By Building A Modal
-React Portals
-Portals 를 통한 부모 컴포넌트의 외부 DOM 에 컴포넌트 렌더링하기

0개의 댓글