티스토리 뷰
Portal 이란?
리액트에서는 root element에 모든 컴포넌트를 올리고 지우고 반복하면서 컴포넌트를 만들었습니다.
포탈은 루트 외의 요소에 컴포넌트를 띄울 수 있게 해줍니다.
공식문서에 따르면 부모 컴포넌트의 DOM 계층 구조 바깥에 있는 DOM 노드로 자식을 렌더링하는 최고의 방법이라고 합니다.
div id="root 인 요소와 div id="portal"인 요소는 형제 관계처럼 보이지만 실제로 portal은 root안에서 보여지는 자식 컴포넌트이고, 렌더링만 root의 바깥에서 이뤄지고 있는 것입니다.(리액트의 tree구조가 리렌더링을 발생시키므로 이럴 때, 부모-자식 관계를 유지하면서 독립적인 위치에서 렌더링을 하면 편리한 경우에 사용, 부모 컴포넌트의 제약에서 벗어나기 위함)
*root element는 index.js 에 있는 이 친구를 말하는데,
const root = ReactDOM.createRoot(document.getElementById("root"));
진짜 root가 있는 곳은 public폴더의 index.html(SPA이니까 하나의 html이 존재하겠죠?) <div id="root"></div>
이 친구를 가져온 것입니다.
사용법
ReactDOM.createPortal(child, container)
- 첫 번째 인자(child): 엘리먼트, 문자열, 혹은 fragment와 같은 어떤 종류이든 렌더링할 수 있는 React 자식
- 두 번째 인자(container): DOM 엘리먼트(진짜 돔!!)
포탈 적용해보기
1. public/index.html 에 <div id="portal"></div> 를 추가해주고
2. 컴포넌트를 새로 만들거나 원래 컴포넌트 js파일에 새로운 Portal용 함수를 만들어줍니다.
저는 따로 컴포넌트를 만들어줬습니다.
- createPortal 메소드를 react-dom에서 임포트 해오고
- createPortal(자식 컴포넌트, 실제 돔 요소 container) //우리가 1번에서 id가 portal인 div요소를 만들어뒀으니 그곳으로 두번째 인자를 지정해주면 되겠습니다.
src/ReactPortal.js
import React from "react";
import { createPortal } from "react-dom";
// 포탈은 dom도 건들여야 하기 때문에 react-dom에서 createPortal을 가져옵시다.
function ReactPortal({ children }) {
return createPortal(children, document.getElementById("portal"));
}
export default ReactPortal;
3. 이렇게 만들어진 ReactPortal 이라는 컴포넌트를 사용하고자 하는 컴포넌트 파일에 불러와 자식 요소로 엘리먼트를 내려주면 내용이 렌더링되는 것을 확인할 수 있습니다.
src/App.js
<ReactPortal>
<p>안녕하세요</p>
</ReactPortal>
Portal은 모달창을 만들 때 유용하게 사용할 거 같습니다.
useState로 모달의 상태 true, false 값을 조절하고 state값이 true일 때만 modal이 렌더링하도록 조건을 걸어주면 모달창을 원하는 때에 띄워줄 수 있습니다. 공식 문서에 Portal이 왜 필요한 지에 대한 내용이 나와있으니 읽어보는 것을 추천드립니다.
https://ko.reactjs.org/docs/portals.html
'Frontend > react.js' 카테고리의 다른 글
[React-Query] react-query 는 무엇이고 어떻게 사용하나요? + React.suspense (0) | 2022.10.24 |
---|---|
[React] 무한스크롤 기능 구현( feat. react-query & react-intersection-observer) (2) | 2022.10.23 |
[React | axios] axios interceptor 사용하기 (0) | 2022.10.22 |
[React] 에러 핸들링, 리액트 ErrorBoundary (0) | 2022.10.20 |
[React] memoization, fetch, useReducer, contextAPI (0) | 2022.10.20 |
- Total
- Today
- Yesterday
- 프리렌더링확인법
- float 레이아웃
- text input pattern
- 항해99프론트후기
- tilde caret
- getStaticPaths
- 타입스크립트 DT
- 원티드 프리온보딩 FE 챌린지
- is()
- ~ ^
- 원티드 3월 프론트엔드 챌린지
- 타입스크립트 장점
- && 셸 명령어
- fs모듈 넥스트
- getServerSideProps
- 원티드 FE 프리온보딩 챌린지
- 부트캠프항해
- 틸드와 캐럿
- nvm경로 오류
- aspect-ratio
- 프리온보딩 프론트엔드 챌린지 3월
- nvm 설치순서
- reactAPI
- 형제 요소 선택자
- grid flex
- 항해99프론트
- 원티드 프리온보딩 프론트엔드 챌린지 3일차
- D 플래그
- Prittier
- 항해99추천비추천
일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
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 |