이번 시간에는 React에서 제공하는 Portals을 이용하여 모달을 생성하고자 한다.
아래의 사진을 보자.
모달 열기 버튼을 눌러 모달을 열었음에도, 기존의 정보(모달열기, z-index 2)가 출력된다
그 다음으로 아래의 코드를 보면 모달 안의 div 요소의 z-index는 1000이다
하지만 그보다 낮은 z-index 2가 항상 화면에서 출력되고 있다
그 이유는 무엇일까/
바로 모달안의 부모 요소의 z-index가 1이기 때문이다.
자식 요소의 z-index의 값이 아무리 높아도 부모 요소의 z-index가 다른 요소보다 낮다면 화면에 출력된다
이것을 어떻게 막을 수 있을까?
-> Portals을 이용하여 모달 생성하면 된다.
이것을 가볍게 설명하자면, Portal은 부모 컴포넌트의 DOM 계층 구조 바깥에 있는 DOM노드로 자식을 랜더링한다
ReactDom.createPortal(child, container)
첫번째 인자(child)는 델리먼트, 문자열, 혹은 fragment와 같은 어떤 종류든 랜더링 가능
두번쨰 인자(container)는 DOM 엘리먼트
를 받는다.
우선 최상위 디렉토리의 index.html에 portal(컨테이너)을 추가한다.
<body>
<div id="root"></div>
<div id="portal"></div>
<script type="module" src="/src/main.jsx"></script>
</body>
그다음 Modal.jsx에서
import ReactDOM from 'react-dom';
return ReactDOM.createPortal(
<>
<div style = {overlayStyle}/>
<div style= {modalStyle}>
{children}
<button onClick = {onClose}>모달 닫기</button>
</div>
</>,
document.getElementById('portal')
)
를 추가해서 실행해보면,
아래와 같이 root 컨테이너에 동등한 portal이기 때문에,
아래와 같이 기존의 요소가 z-index 우선순위에 의해 화면에서 가려짐을 확인할 수 있다.(요소는 존재)
Portal의 특징중 하나는 이벤트 버블링이 가능하다
이벤트 버블링 : 중첩된 자식 요소에서 이벤트가 발생할 때 그 이벤트가 부모로 전달 되는 것
'
비록 Portal로 생성한 부분이 부모 DOM 밖에 생성되더라도(DOM 트리에서의 위치에 상관없이) portal은 여전히 React 트리에 존재해서 React 트리에 포함된 상위로 이벤트 버블링이 가능하다.
요약: DOM 트리 상위가 아니라도 리액틀 트리에서 상위이면 이벤트 버블링 가능
부모 요소에서 console.log를 추가해서,
<div onClick = {() => console.log('clicked')} style={modalWrapperStyle}>
<button onClick={ () => setIsModalOpen(true)}>모달 열기</button>
자식 요소인 Modal에서 버튼을 클릭해도
위 화면에서와 같이, clicked가 출력됨을 확인할 수 있다.
'패스트캠퍼스 데브캠프' 카테고리의 다른 글
김민태의 데브캠프 2기 - firebase로 배포하기 (0) | 2024.11.14 |
---|---|
김민태의 데브캠프 2기 - firebase를 사용한 로그인 구현 (0) | 2024.11.14 |
김민태의 데브캠프 2기 - Forward Ref에 대해 알아보자 (1) | 2024.11.13 |
김민태의 데브캠프 2기 - useRef를 이용해서 변수 관리하기 (0) | 2024.11.13 |
김민태의 데브캠프 2기 - 실시간 강의 (11/13) 정리 (1) | 2024.11.13 |