티스토리 뷰
올 해 1월, 원티드 프리온보딩 프론트엔드 챌린지를 수강하는 기간동안 디스코드에서 많은 사람들의 경험을 공유받았다. 이 때, 사람들이 모달 생성에 대해 이야기를 나눴고, 이 때, 한 사람이 "createPortal()"에 대해 언급했다. 모달창을 생성하기 위해서 한 가지 방법이라고 추천을 해준 것이다.
이 당시 나는 모달창 생성을 구현하고 있었고, "createPortal()"를 처음 알게 되면서 궁금함이 생겨 공식 문서를 찾아봤다. 생각보다 여러 가지 활용법이 있었고, 그 중 하나가 모달이었다.
구현도 생각보다 단순했다. 그렇지만, 당장 활용할 가치가 있는지 의문이 들었다. 왜냐하면, 개발중인 프로젝트는 모달 컴포넌트를 재사용할 필요가 없는 상황이었고, 예시 코드를 봤을 때, 오히려 컴포넌트의 개수만 늘어날 뿐이라고 느꼈다.
그렇지만, "모달을 어떤 상황에서 어떻게 사용할 것인가?", "재사용이 적극 필요한 부분인가?"에 대해 고민한다면 충분히 활용을 고려해도 될 것 같다는 생각이 들었다.
예시 코드는 아래와 같다.
import NoPortalExample from './NoPortalExample';
import PortalExample from './PortalExample';
export default function App() {
return (
<>
<div className="clipping-container">
<NoPortalExample />
</div>
<div className="clipping-container">
<PortalExample />
</div>
</>
);
}
두 개의 경우를 가정한다. 하나는 "createPortal()"을 사용하지 않은 것, 또 하나는 "createPortal()"를 사용한 것이다.
"createPortal()"를 사용하지 않은 코드는 다음과 같다.
import { useState } from 'react';
import ModalContent from './ModalContent.js';
export default function NoPortalExample() {
const [showModal, setShowModal] = useState(false);
return (
<>
<button onClick={() => setShowModal(true)}>
Show modal without a portal
</button>
{showModal && (
<ModalContent onClose={() => setShowModal(false)} />
)}
</>
);
}
"createPortal()"를 사용하지 않아 실제로 모달 버튼을 누르면, 버튼 아래에 "ModalContent"의 내용이 나타난다. 이는, 우리가 원하는 모달의 모습이 아니다.
반대로 "createPortal()"를 사용한다면?
import { useState } from 'react';
import { createPortal } from 'react-dom';
import ModalContent from './ModalContent.js';
export default function PortalExample() {
const [showModal, setShowModal] = useState(false);
return (
<>
<button onClick={() => setShowModal(true)}>
Show modal using a portal
</button>
{showModal && createPortal(
<ModalContent onClose={() => setShowModal(false)} />,
document.body
)}
</>
);
}
기대하는 모달의 모습으로 "ModalContent"의 내용이 나타나게 된다. 이 때, "createPortal()"을 사용할 때 필수적으로 넣어줘야 할 값은 "children"과 "domNode"이다.
- children: 렌더링할 React 컴포넌트(요소)
- domNode: 컴포넌트가 렌더링될 실제 DOM 노드(→ 나타낼 내용)
위의 "createPortal()"를 사용한다면, React 트리에서 벗어나 별도의 DOM 요소에 렌더링을 원할 때 사용하길 권장된다.
즉, 단순히 모달창을 구현하기 위한 목적이라면 이보다 다른 라이브러리인 "react-modal"을 사용하는 것이 더 낫다고 판단된다. 그 이유는 "createPortal()"을 활용해 모달창을 구현할 경우, 모달의 위치나 포커스 관리 등 세부적인 부분을 직접 처리해야 하는 단점이 존재한다. 그렇기 때문에, 단순히 모달창을 구현하려고 한다면 모달로써 기능을 갖추고 있는 "react-modal"을 고려해보자.
npm install react-modal
먼저, "react-modal"을 설치한다. 그리고 <ReactModal> 또는 <Modal>을 호출해서 사용하면 되는데, 이 때, 상황에 따라 에러가 나는 경우가 있으니, 구글 검색을 통해 각자의 환경 및 상황에 따라 해결하면 될 것 같다.
나는 "react-modal"을 아래처럼 활용했다.
import Modal from "react-modal";
<Modal
isOpen={isOpen!}
onRequestClose={closeVideo}
contentLabel="Video"
style={{
content: {
width: "820px",
height: "530px",
margin: "auto",
border: "none",
backgroundColor: "transparent",
},
overlay: {
backgroundColor: "rgba(0, 0, 0, 0.5",
},
}}
>
{renderModalContent()}
</Modal>
"isOpen"은 무조건 값이 있다는 설정을 해주었고, 그 외에 라벨과 닫기 이벤트, 스타일 등을 지정해주었다.
그리고, Modal에 children에 나타낼 내용들을 담아주었다.
직접 스타일을 줌으로써 구현하는 것은 이보다 더 복잡했고, 가독성에 문제가 있었지만, "react-modal" 라이브러리를 활용하고 나니 전보다 더 읽고 관리하기 쉬워진 느낌을 가질 수 있었다.
그러나, 스타일을 지정할 때, 크기 부분에 있어서는 나타낼 내용의 크기보다 조금 더 크게 설정해야 딱 맞는 크기로 나타낼 수 있는 것이 조금 아쉬웠다. (이 부분은 나만 해당될 수도..)
"createPortal()"은 나중에 간단하게 텍스트를 나타낼 모달창이나 툴팁을 나타내고자 할 때 활용할 계획이다.
'프론트엔드 > React' 카테고리의 다른 글
useMemo는 언제 사용해야 할까? (0) | 2024.03.29 |
---|---|
useQuery에서 RTK Query로 데이터 가져오기 (0) | 2024.03.21 |
트위터 기반으로 Pet 전문 플랫폼을 만들 계획입니다. (0) | 2024.01.13 |
Slash23 프론트엔드, 접근 과정 최적화 코드로 학습 (0) | 2023.08.23 |
프론트엔드 성능 최적화하기 (0) | 2023.08.15 |
- Total
- Today
- Yesterday
- Frontend
- React
- Express
- if(kakao)dev2022
- 프론트엔드 챌린지
- 스프링
- 개발 이력서 지원 팁
- #포스텍애플디벨로퍼아카데미
- 깃허브 Merge
- 설명회느낌점
- 원티드 프리온보딩 챌린지
- 최종추가합격
- Singleton
- node
- javascript
- 신입개발자가 준비해야 할 것들
- DB Error MongooseServerSelectionError
- 자바스크립트
- 개발자이력서꿀팁
- 포스텍애플디벨로퍼아카데미
- 코딩테스트 대비
- PostechAppleDeveloperAcademy
- 그룹인터뷰후기
- 원티드 프리온보딩
- Default Branch
- 싱글톤
- 포스텍애플아카데미
- LottieFiles
- 조코딩과함께
- 고민한 부분
일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | 2 | 3 | ||||
4 | 5 | 6 | 7 | 8 | 9 | 10 |
11 | 12 | 13 | 14 | 15 | 16 | 17 |
18 | 19 | 20 | 21 | 22 | 23 | 24 |
25 | 26 | 27 | 28 | 29 | 30 | 31 |