React Portal ์ฌ์ฉํ๊ธฐ
๐์์ํ๋ฉฐ
์ต๊ทผ ๊ฐ์๋ฅผ ์๊ฐํ๋ฉฐ ํ์ต์ฉ ํ๋ก์ ํธ๋ฅผ ์งํ ์ค์ด๋ค. ๊ฐ์ ๋ด์ฉ ์ค์ React Portal์ ์ฌ์ฉํด Modal์ ๋ง๋๋ ๋ถ๋ถ์ด ๋์ค๋๋ฐ, ํด๋น ๊ธฐ๋ฅ์ ์กด์ฌ๋ ์๊ณ ์์์ง๋ง ์ค์ ํ๋ก์ ํธ์ ์ ์ฉํด๋ณด๋ ๊ฑด ์ฒ์๋ผ์, ๊ฐ์ ๋ด์ฉ์ ๊ธฐ๋ฐ์ผ๋ก ์ค์ค๋ก ํ์ตํ ๋ด์ฉ์ ์ถ๊ฐํด ์ ๋ฆฌํด๋ณด๊ณ ์ ํ๋ค.
โ React Portal ์ด๋
๊ณต์๋ฌธ์์์๋ ์ด ๊ธฐ๋ฅ์ ๋ค์๊ณผ ๊ฐ์ด ์ค๋ช ํ๋ค.
Portal์ ๋ถ๋ชจ ์ปดํฌ๋ํธ์ DOM ๊ณ์ธต ๊ตฌ์กฐ ๋ฐ๊นฅ์ ์๋ DOM ๋ ธ๋๋ก ์์์ ๋ ๋๋งํ๋ ์ต๊ณ ์ ๋ฐฉ๋ฒ์ ์ ๊ณตํฉ๋๋ค.
๊ธ๋ก๋ง ๋ณด๋ฉด ์ดํดํ๊ธฐ ์ด๋ ค์ด๋ฐ, ์ฝ๋๋ก ๋ณด๋ฉด ์ดํดํ๊ธฐ ์ฝ๋ค. React์ index.html
ํ์ผ์ ์ดํด๋ณด์. ๊ธฐ๋ณธ์ ์ผ๋ก๋ ๋ค์๊ณผ ๊ฐ์ ๊ตฌ์กฐ๋ฅผ ๊ฐ์ง๊ณ ์๋ค.
1
2
3
4
<body>
<noscript>You need to enable JavaScript to run this app.</noscript>
<div id="root"></div>
</body>
๊ทธ๋ฆฌ๊ณ ์ฐ๋ฆฌ๊ฐ ๋ง๋๋ ์ปดํฌ๋ํธ๋ค์ <div id="root"></div>
์ ์์์ ๋ ๋๋ง ๋๊ฒ ๋๋ค. ํ์ง๋ง Portal์ ์ฐ๋ฉด ์ด ๋ด๋ถ์์ ๋ ๋๋ง ๋๋๊ฒ์ด ์๋๋ผ ์ธ๋ถ DOM ์์์ ๋ ๋๋ง ํ ์ ์๋ค.
์๋ฅผ ๋ค์ด, ๋ค์๊ณผ ๊ฐ์ ํ์์ ๊ฐ์ง ์ ์๋ค. ์ด๋ ๊ฒ ํ๋ฉด, Modal์ ๋ง๋ค ๋ id=โrootโ์์์ ์์ ๋ก์์ง๋ฏ๋ก ๋ค๋ฅธ ์์๋ค์ z-index๋ ๋ถ๋ชจ ์์๋ก๋ถํฐ์ ์คํ์ผ ์ํฅ์ ๋ฐ์ง ์์, ํจ์ฌ ํธ๋ฆฌํ๊ฒ Modal์ ๋ง๋ค ์ ์๋ค.
1
2
3
4
5
<body>
<noscript>You need to enable JavaScript to run this app.</noscript>
<div id="root"></div>
<div id="portal"></div>
</body>
โ React Portal ์ฌ์ฉํ๊ธฐ
โก๏ธ์ธ๋ถ DOM์์ ์์ฑํ๊ธฐ
๋จผ์ index.html
์ ์ธ๋ถ DOM ์์๋ฅผ ์์ฑํด์ค๋ค.
1
2
3
4
5
<body>
<noscript>You need to enable JavaScript to run this app.</noscript>
<div id="root"></div>
<div id="portal" ๐></div>
</body>
โก๏ธcreatePortal์ ์ฌ์ฉํด ๋ ๋๋ง ํ๊ธฐ
๐createPortal์ด๋?
createPortal(children, domNode, key?)
portal์ ์์ฑํ๋ ค๋ฉด createPortal์ ํธ์ถํ๋ฉด ๋๋ค. createPortal์ 2๊ฐ์ง ์ธ์์ 1๊ฐ์ง ์ต์
์ ๊ฐ๋๋ค. |๊ฐ|์ค๋ช
| |โ|โ| |children|element, component ๋ฑ React๋ก ๋ ๋๋งํ ์ ์๋ ๋ชจ๋ ๊ฒ| |domNode|document.getElementById()
๋ฅผ ํตํด ์ป์ ์ ์๋ DOM ๋
ธ๋.
์ฆ, ํด๋น ๋
ธ๋๋ ์ด๋ฏธ ์กด์ฌํด์ผ ํ๋ค.
์
๋ฐ์ดํธ ์ค์ ๋ค๋ฅธ DOM ๋
ธ๋๋ฅผ ์ ๋ฌํ๋ฉด ํฌํธ ์ฝํ
์ธ ๊ฐ ๋ค์ ์์ฑ๋๋ค.| |key(์ต์
)|ํฌํธ์ ํค๋ก ์ฌ์ฉํ ๊ณ ์ ํ ๋ฌธ์์ด ๋๋ ์ซ์|
๐์ฌ์ฉ์์
์์์ index.html
์ ์ธ๋ถ DOM ์์์ธ <div id="portal" ๐></div>
๋ฅผ ์์ฑํด ๋์์ผ๋ฏ๋ก, ์ด๊ฒ๊ณผ ํจ๊ป ๋ฏธ๋ฆฌ ๋ง๋ค์ด ๋ Modal ์ปดํฌ๋ํธ๋ฅผ ๊ฐ์ ธ์์ ์ฌ์ฉํด๋ณด์.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
import { createPortal } from "react-dom"
import MainContent from "@component/MainContent"
import Modal from "@component/Modal"
const modalDiv = document.getElementById("portal")
export default function App() {
return (
<>
<MainContent />
{createPortal(<Modal />, modalDiv)}
</>
)
}
๐Modal Open & Close
์ถ๊ฐ์ ์ผ๋ก, Modal์ ์ด๊ณ ๋ซ๋ ๊ฒ์ ๊ด๋ฆฌํ๋ ค๋ฉด ๋ค์๊ณผ ๊ฐ์ด ํ ์ ์๋ค.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
import { createPortal } from "react-dom"
import MainContent from "@component/MainContent"
import Modal from "@component/Modal"
const modalDiv = document.getElementById("portal")
export default function App() {
const [modalOpen, setModalOpen] = useState(false)
const openModal = () => {
setModalOpen(true)
}
const closeModal = () => {
setModalOpen(false)
}
return (
<>
<MainContent />
{modalOpen && createPortal(<Modal onClose={closeModal} />, modalDiv)}
</>
)
}
๐ฉ๋ง๋ฌด๋ฆฌ
์ด๋ ๊ฒ portal์ ์ด์ฉํด์ ๋ชจ๋ฌ์ ๋ง๋๋ ๋ฐฉ๋ฒ์ ๋ํด ์์๋ดค๋ค. ๊ด๋ จ ๋ด์ฉ์ ๊ฒ์ํ๋ค๊ฐ <dialog>
ํ๊ทธ๋ฅผ ์๊ฒ ๋์๋๋ฐ ์ด๊ฑด ์ด์ด์ ๋ค์ ํฌ์คํ
์์ ์ ๋ฆฌํ๊ณ ์ํ๋ค.
๐๏ธ์ฐธ๊ณ ์ฌ์ดํธ
- https://ko.legacy.reactjs.org/docs/portals.html
- https://react.dev/reference/react-dom/createPortal