React Portal

React์—๋Š” ์ฐธ ์‹ ๊ธฐํ•œ๊ฒŒ ๋งŽ๋‹ค. ๋ณ„๋ณ„ ๊ฒƒ๋“ค์„ ๋‹ค ํ•ด๋†“๊ณ  ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ๋ผ๊ณ  ์šฐ๊ธฐ๋Š”๊ฒŒ ๋˜๊ฒŒ ์ดˆ๋ณด ์‚ฌ๋ƒฅํ„ฐ์—์„œ ๋…์‹ํ•˜๋Š” ๊ณ ์ธ๋ฌผ๊ฐ™๋‹ค..

์•”ํŠผ React Portal์€ ๋ถ€๋ชจ ์ปดํฌ๋„ŒํŠธ์˜ DOM ๊ณ„์ธต ๊ตฌ์กฐ ๋ฐ”๊นฅ์— ์žˆ๋Š” DOM ๋…ธ๋“œ๋กœ ์ž์‹์„ ๋ Œ๋”๋งํ•˜๋Š” ๋ฐฉ์‹์„ ์ œ๊ณตํ•œ๋‹ค. ๊ฐ„๋‹จํ•˜๊ฒŒ ์ƒ๊ฐํ•ด๋ณด์ž๋ฉด ์ž์‹ ์ปดํฌ๋„ŒํŠธ๋ฅผ ๋‹ค๋ฅธ ๊ณณ์— ๊ฐ–๋‹ค ์ „๋‹ฌํ•  ์ˆ˜ ์žˆ๋‹ค๋Š” ๋œป์ด๋‹ค.

์™œ ์‚ฌ์šฉํ• ๊นŒ?

React์˜ ํŠธ๋ฆฌ ๊ตฌ์กฐ์— ๋”ฐ๋ผ์„œ ๋ถ€๋ชจ ์ปดํฌ๋„ŒํŠธ๊ฐ€ ๋ Œ๋”๋ง ๋  ๊ฒฝ์šฐ์— ์ž์‹ ์š”์†Œ ๋˜ํ•œ ๋”ฐ๋ผ์„œ ๋ Œ๋”๋ง ๋  ์ˆ˜๋ฐ–์— ์—†๋‹ค. ํ•˜์ง€๋งŒ ๋งŒ์•ฝ ์ž์‹ ์š”์†Œ๊ฐ€ ๋ฐ”๋€Œ์ง€ ์•Š๋Š”๋‹ค๋ฉด ๊ตณ์ด ๋ Œ๋”๋ง์„ ๋‹ค์‹œ ํ•  ํ•„์š”๊ฐ€ ์—†๊ณ , ์„ฑ๋Šฅ์„ ๋–จ์–ด๋œจ๋ฆฌ๋Š” ์›์ธ๋ฐ–์— ๋˜์ง€ ์•Š์œผ๋ฏ€๋กœ ํฌํƒˆ์„ ์‚ฌ์šฉํ•œ๋‹ค.

๊ทธ๋ ‡๊ฒŒ ํฌํƒˆ๋กœ ์ž์‹ ์ปดํฌ๋„ŒํŠธ๋ฅผ ๋ฐ”๊นฅ์— ๋‚ด๋†“์Œ์œผ๋กœ์จ ์ด๋Ÿฌํ•œ ๋ฌธ์ œ๋ฅผ ํ•ด๊ฒฐํ•จ๊ณผ ๋™์‹œ์— DOM ์š”์†Œ์—์„œ๋Š” ๋ถ€๋ชจ-์ž์‹๊ด€๊ณ„์ฒ˜๋Ÿผ ๋ณด์ด์ง€๋งŒ ์ด๋ฅผ ๋…๋ฆฝ์ ์œผ๋กœ ๊ด€๋ฆฌํ•  ์ˆ˜ ์žˆ๊ธฐ ๋•Œ๋ฌธ์— ์‚ฌ์šฉํ•œ๋‹ค.

์‚ฌ์šฉํ•˜๊ธฐ

createPortal(children)

<div>
  <SomeComponent />
  {createPortal(children, domNode, key?)}
</div>
 
// ์ ์šฉ ์˜ˆ์‹œ
import { createPortal } from 'react-dom';
 
// ...
 
<div>
  <p>This child is placed in the parent div.</p>
  {createPortal(
    <p>This child is placed in the document body.</p>,
    document.body
  )}
</div>

ํฌํƒˆ์„ ์‚ฌ์šฉํ•˜๊ธฐ ์œ„ํ•ด์„œ๋Š” createPortal์„ ์‹คํ–‰ํ•˜์—ฌ ํฌํƒˆ์„ ์ƒ์„ฑํ•ด์•ผ ํ•œ๋‹ค.

  • children: JSX ์กฐ๊ฐ (์˜ˆ: <div /> ๋‚˜ <SomeComponent />), Fragment (<>...</>), ๋ฌธ์ž์—ด์ด๋‚˜ ์ˆซ์ž, ๋˜๋Š” ์ด๋“ค์˜ ๋ฐฐ์—ด๊ณผ ๊ฐ™์ด React๋กœ ๋ Œ๋”๋งํ•  ์ˆ˜ ์žˆ๋Š” ๋ชจ๋“  ๊ฒƒ.
  • domNode: document.getElementById()๊ฐ€ ๋ฐ˜ํ™˜ํ•˜๋Š” ๊ฒƒ๊ณผ ๊ฐ™์€ ์ผ๋ถ€ DOM ๋…ธ๋“œ์ด๋‹ค
    • ๋…ธ๋“œ๋Š” ์ด๋ฏธ ์กด์žฌํ•˜๊ณ  ์žˆ์–ด์•ผ ํ•œ๋‹ค. ์—…๋ฐ์ดํŠธ ์ค‘์— ๋‹ค๋ฅธ DOM ๋…ธ๋“œ๋ฅผ ์ „๋‹ฌํ•˜๋ฉด ํฌํ„ธ ์ฝ˜ํ…์ธ ๊ฐ€ ๋‹ค์‹œ ์ƒ์„ฑ๋œ๋‹ค
  • ์„ ํƒ์  key: ํฌํ„ธ์˜ ํ‚ค๋กœ ์‚ฌ์šฉํ•  ๊ณ ์œ  ๋ฌธ์ž์—ด ๋˜๋Š” ์ˆซ์ž ์ด๋ ‡๊ฒŒ ํฌํƒˆ์„ ์ƒ์„ฑํ•˜๋ฉด ๋ฐ˜ํ™˜๊ฐ’์œผ๋กœ React node๋ฅผ ๋ฐ˜ํ™˜ํ•œ๋‹ค. ๋ฆฌ์•กํŠธ๋Š” ๋ Œ๋”๋ง ์ค‘์— ์ด ํฌํƒˆ๋กœ ๋งŒ๋“ค์–ด์ง„ React node๋ฅผ ๋ณด๋ฉด ์ œ๊ณต๋œ children์„ ์„ค์ •ํ•œ domNode ์•ˆ์— ๋ฐฐ์น˜ํ•œ๋‹ค.

๋”ฐ๋ผ์„œ ์œ„์™€ ๊ฐ™์€ ์˜ˆ์‹œ๋กœ ํฌํƒˆ์„ ๋งŒ๋“ค๊ฒŒ ๋˜๋ฉด ํ˜„์žฌ ์ฝ”๋“œ ์ƒ์—์„œ <p>This child is placed in the document body.</p>๋Š” ํ˜„์žฌ ์šฐ๋ฆฌ๊ฐ€ ๋ณด๋Š” ๊ฒƒ๊ณผ ๊ฐ™์ด div ํƒœ๊ทธ์˜ ์ž์‹ ์š”์†Œ์ฒ˜๋Ÿผ ๋ณด์ด์ง€๋งŒ ์‹ค์ œ๋กœ ๋ Œ๋”๋ง ํ•  ๋•Œ๋ฅผ ๋ณด๋ฉด ๋‹ค๋ฅด๋‹ค.

<body>
  <div id="root">
    ...
      <div style="border: 2px solid black">
        <p>This child is placed inside the parent div.</p>
      </div>
    ...
  </div>
  <p>This child is placed in the document body.</p>
</body>

๋งˆ์น˜ ์ด๋Ÿฐ์‹์œผ๋กœ ํฌํƒˆ์„ ํ†ตํ•ด ๋ฟ…~ ๋„˜์–ด๊ฐ„ ๋’ค document์˜ body์ชฝ์œผ๋กœ ์ด๋™ํ•œ ๊ฒƒ์ด๋‹ค.