-
굳이 createPortal로 모달을 만드는 이유는?REACT 2025. 12. 8. 15:00

포탈하니까 갑자기 바람의나라 하고싶어서 가져옴 createPortal
게임에서 포탈을 타고 다른 맵으로 이동하듯,
createPortal은 React 컴포넌트를 특정 DOM 위치로 “텔레포트”하듯 렌더링할 수 있는 API이다.createPortal(children, domNode, key?)children : 이동하고자 하는 컴포넌트, jsx 입력
domNode: 텔레포트 시킬 dom
key? : portal의 key값을 부여할수있는 선택옵션 인자
일반 div Modal과 createPortal Modal 비교
보통 모달구현할때 dom의 최상단에 위치시키려고
position:fixed, z-index:99999 이런식으로 스타일링을 하는데부모 요소에 의해 새로운 stacking context가 생성되면, 자식의 z-index가 아무리 커도
다른 stacking context에 속한 요소와는 비교되지 않아 의도치 않게 가려지는 문제가 발생한다.
(실제로 이런경우 겁나 많음)
무슨말인지 모르겠으면 아래 예제를 보자
- 일반적인 div Modal
- 빨간박스는 z-index : 10
- createPortal Modal
div Modal은 z-index:50이지만 부모요소에서 stacking context가 생성되어 빨간박스 밑으로 가려지게되고
반면 createPortal은 React 컴포넌트 트리와는 유지된 상태로,
DOM에서의 노드(보통 document.body)에 렌더링되기 때문에 stacking context로 부터 자유로워지게 되는것이다.
stacking context
번역하면 쌓임맥락이라고 하는데
그게 중요한게 아니고가상의 z축을 따라 HTML을 3차원으로 개념화한 용어이다.쉽게 이야기하면 각 요소를 따져 누가 먼저 보여지고, 가려지게되는지를 추상화해보는 개념(?) 라고 생각해보면 될거같다.
여러 요소에 따라 결정나겠지만 대표적으로 z-index값이 있겠다
헷갈리게 이벤트 버블링은 컴포넌트 기준으로 된다.
createPortal로 dom최상위에 렌더링 시켯다고 해서 해당 dom에서만 이벤트버블링이 먹힐거라 생각하겠지만
실제로 실행해보면 html dom이 아닌 리액트 컴포넌트 기준으로 먹히기때문에 이것을 주의해서 구현해야한다.
잘 활용하면 득일수도 있는데 부모 컴포넌트에 이벤트가 있다면 독이 될수도...?
마무리
수업들을땐
아,이건또뭐지 멍때렸는데
생각해보니까 지금하고있는 사이드프로젝트에서 모달을 createPortal로 구현했던게 생각이 났다.사실 내가 구현했던 코드가 아니라 새싹 팀원이였던 우리님이 만드신거라 몰랐었는데,
덕분에 동료의 코드리뷰에 소홀히하면 안되겠단 생각이 들었다,,ㅠ그래도 오늘 수업으로 깨달아서 다행이당 강사님 쵝오..👍
참고자료
모달 만들 때 왜 createPortal 쓰세요?
저는 아는데.. 🤓
velog.io
https://pozafly.github.io/css/stacking-context/
왜 내 z-index는 먹히지 않는가?
z-index가 때로 적용이 되지 않는 문제를 해결하기 위해 stacking context에 대해 정확히 알아본다.
pozafly.github.io
https://mongsira.tistory.com/52
[React] react portal로 모달창 만들기 (feat. 이벤트 버블링)
프로젝트를 진행하면서 본격적인 페이지 구현에 들어가기에 앞서 모달창 구현을 맡았다.전체적인 모달창은 react portal을 이용해 만들었다. 처음에 프로젝트를 진행하기 전까지 react portal을 몰
mongsira.tistory.com
'REACT' 카테고리의 다른 글
Virtual DOM부터 Memoization까지 (0) 2025.12.29 시작한건 끝내야하는 useEffect, 그리고 return (0) 2025.12.11 Props 요리조리 구워삶기 - Context API & Props Drilling (1) 2025.12.10 useState, 제대로 알고 쓰시나요? (0) 2025.12.09 useReducer로 상태관리 연습해보기 (0) 2025.12.02