2021. 12. 11. 23:50ㆍReactJS/Information
createPortal은 React-dom에서 지원하는 기능으로 v16부터 지원을 시작하였다.
먼저 createPortal의 함수부터 알아보자.
createPortal
- Node를 원하는 Element 안으로 이동 시키는 함수
- DOM Tree에서 다른 곳으로 이동 시키는 함수
- DOM Tree에서만 이동을 시키고, 실제 React Tree에서는 이동되지 않기 때문에 React 자식요소처럼 작동한다.
그렇기 때문에 이벤트 버블링 또한 React Tree에 맞게끔 작동 된다.
1
2
|
// in react-dom
export function createPortal(children: ReactNode, container: Element, key?: null | string): ReactPortal;
|
cs |
첫번째 인자로 이동할 ReactNode를 넣고, 두번째 인자로 이동될 container의 Element를 넣어줘야 하는 것 같다.
그럼 이 함수를 언제, 왜 써야할까?
- 언제?, 왜?
React는 부모 컴포넌트가 렌더링되면 자식 컴포넌트가 렌더링되는 Tree 구조를 가지고 있다.
하지만 때때로 이런 구조가 불편함을 가져다주기도 한다. 분명 부모-자식 관계를 가지고 있지만 독립적인 위치에서 렌더링을 하면 훨씬 편리한 경우가 있다.
대표적인 예로 Modal 은 부모 컴포넌트의 스타일링 속성에 제약을 받아 z-index 등으로 번거로운 후처리를 해줘야한다.
이러한 상황에서 Portal을 통해 독립적인 구조와 부모-자식 관계를 동시에 유지할 수 있다면, z-index 등 부모 컴포넌트의 제약에서 벗어날 수 있다.
그럼 한번 실제로 구현해보자.
먼저 /public/index.html에 아래와 같이 root 위에 portal-wrap 이라고 div를 만들어주자.
(id는 강제되는 요소가 아니라 본인이 직접 정하면 된다.)
index.html
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
|
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8" />
<link rel="icon" href="%PUBLIC_URL%/favicon.ico" />
<meta name="viewport" content="width=device-width, initial-scale=1" />
<meta name="theme-color" content="#000000" />
<meta name="description" content="Web site created using create-react-app"/>
<link rel="apple-touch-icon" href="%PUBLIC_URL%/logo192.png" />
<title>React App</title>
</head>
<body>
<noscript>You need to enable JavaScript to run this app.</noscript>
<div id="portal-wrap"></div>
<div id="root"></div>
</body>
</html>
|
cs |
그리고 Portal의 편리한 사용을 위해 Portal.ts를 하나 만들어주도록 하자.
Portal.ts
1
2
3
4
5
|
import ReactDOM from "react-dom"
export default function Portal({children}: any) {
return ReactDOM.createPortal(children, document.getElementById("portal-wrap") as Element)
}
|
cs |
(Portal에 적혀있는 Props의 타입이 뭔지를 도대체 모르겠는데.. 알아봐야겠다.)
앞으로 <Portal> ... 이동시킬 DOM ...</Portal> 로 사용 하면 된다.
그럼, 하나를 옮겨보고 확인해보자.
먼저 옮기기 전의 DOM 구조다.
위에 보이는 <span>TEST</span> 을 portal-wrap으로 옮겨보도록 하겠다.
1
2
3
4
5
|
import Portal from './Portal';
<Portal>
...
</Portal>
|
cs |
이런식으로 해서 이제 요소를 옮기면 된다.
잘 옮겨졌다.
'ReactJS > Information' 카테고리의 다른 글
[React.js] Lazy Image Component (0) | 2021.12.15 |
---|---|
[React.js] React Query(useQuery, useMutation) (0) | 2021.12.14 |
[React.js] 최상위 API React.memo (0) | 2021.12.11 |
[React.js] Hook 정리 (0) | 2021.12.11 |
[React.js] Redux & Reducer (0) | 2021.12.09 |