ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • [react] deepDive 10 Portals(ํฌํƒˆ)
    react 2023. 12. 22. 17:18

    ๐ŸŽฏ Wrapper ๋ž€?

    => ๋ถˆํ•„์š”ํ•œ ์ค‘์ฒฉ์„ ํ”ผํ•˜๊ธฐ ์œ„ํ•ด ์‚ฌ์šฉํ•˜๋Š” ํƒœ๊ทธ

    Wrapper๋ผ๋Š” ์ปดํฌ๋„ŒํŠธ๋ฅผ ๋งŒ๋“ค์–ด์„œ ๊ฐ์‹ธ๋Š” ์—ญํ• ์„ ํ•˜๋Š” ๊ฒฝ์šฐ์—๋Š” ์•„๋ž˜์™€ ๊ฐ™์ด ๊ฐ„๋‹จํ•œ ํ˜•ํƒœ๋กœ ์ž‘์„ฑํ•  ์ˆ˜ ์žˆ์Œ

    ์ด ์ปดํฌ๋„ŒํŠธ๋Š” ์ž์‹ ์ปดํฌ๋„ŒํŠธ๋“ค์„ ๊ฐ์‹ธ์„œ ํŠน์ •ํ•œ ์Šคํƒ€์ผ์ด๋‚˜ ๋ ˆ์ด์•„์›ƒ์„ ์ ์šฉํ•  ๋•Œ ์‚ฌ์šฉ๋  ์ˆ˜ ์žˆ๋‹ค

    const Wrapper = (props) => {
      return props.children;
    };
    export default Wrapper;

     

    ๐ŸŽฏ Fragment ๋ž€?

    => ๊ฐ„๊ฒฐํ•œ ์ฝ”๋“œ๋ฅผ ์ž‘์„ฑํ•˜๋Š”๋ฐ ๋„์›€์ฃผ๋Š” ํƒœ๊ทธ

    ์ตœ์ข… ํŽ˜์ด์ง€์— ๋ถˆํ•„์š”ํ•œ HTML์š”์†Œ๋“ค์ด ํ‘œ์‹œ ๋˜์ง€ ์•Š์Œ

    ๋ฐฉ๋ฒ• 1

    <>
      <AddUser onAddUser={addUserHandler} />
      <UsersList users={usersList} />
    </>;

    ๋ฐฉ๋ฒ• 2

    <React.Fragment>
      <AddUser onAddUser={addUserHandler} />
      <UsersList users={usersList} />
    </React.Fragment>;

    ๋ฐฉ๋ฒ• 3

    import React, { Fragment } from "react";
        <Fragment>
          <AddUser onAddUser={addUserHandler} />
          <UsersList users={usersList} />
        </Fragment>

     

    <div>ํƒœ๊ทธ ์ผ์„๋•Œ

    <Fragment>ํƒœ๊ทธ ์ผ์„ ๋•Œ

    => ํ™”๋ฉด์— <Fragment>ํƒœ๊ทธ์š”์†Œ๊ฐ€ ๋‚˜ํƒ€๋‚˜์ง€ ์•Š์Œ

     

    ๐ŸŽฏ portal

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

    =>Portals๋Š” ํŠน์ • UI ์š”์†Œ๋ฅผ DOM ๊ตฌ์กฐ์—์„œ ๋ถ„๋ฆฌํ•˜์—ฌ ๋ Œ๋”๋งํ•˜๊ณ  ๊ด€๋ฆฌํ•  ์ˆ˜ ์žˆ๊ฒŒ ํ•ด์ฃผ์–ด, ๋” ์œ ์—ฐํ•˜๊ณ  ๊ฐ•๋ ฅํ•œ UI ํŒจํ„ด์„ ๊ตฌํ˜„ํ•  ์ˆ˜ ์žˆ์Œ

    ํฌํƒˆ์„ ์‚ฌ์šฉํ•˜๊ธฐ ์œ„ํ•ด์„  ๋‘๊ฐ€์ง€๊ฐ€ ํ•„์š”ํ•จ

    ๐Ÿšช ์ปดํฌ๋„ŒํŠธ๋ฅผ ์ด๋™์‹œํ‚ฌ ์žฅ์†Œ

    ๐Ÿ”› ์ปดํฌ๋„ŒํŠธ๋ฅผ ์ด๋™ํ•˜๊ฒ ๋‹ค๋Š” ํ‘œ์‹œ

     

    1. ์ปดํฌ๋„ŒํŠธ๋ฅผ ์ด๋™์‹œํ‚ฌ ์žฅ์†Œ

    publicํด๋”์— ์ปดํฌ๋„ŒํŠธ๋ฅผ ์ด๋™์‹œํ‚ฌ ์žฅ์†Œ๋ฅผ ๋ช…์‹œํ•ด์•ผํ•จ 

    <div id="backdrop-root"></div>
    <div id="overlay-root"></div>
    <div id="root"></div>

     

    2. ReactDOM.createPortal

    ๋ฆฌ์•กํŠธ์—์„œ ํฌํƒˆ์„ ์ƒ์„ฑํ•œ๋Š” ๋ฉ”์„œ๋“œ

    import ReactDOM from "react-dom";
    
    ReactDOM.createPortal(child, container)
    • child: ๋ Œ๋”๋งํ•  React ์š”์†Œ ๋˜๋Š” ์ปดํฌ๋„ŒํŠธ
    • container: child๊ฐ€ ๋ Œ๋”๋ง๋  ๋Œ€์ƒ DOM ๋…ธ๋“œ
    import React from "react";
    import ReactDOM from "react-dom";
    import Card from "./Card";
    import Button from "./Button";
    import classes from "./ErrorModal.module.css";
    
    const Backdrop = (props) => {
      return <div className={classes.backdrop} onClick={props.onConfirm} />;
    };
    
    const ModalOverlay = (props) => {
      return (
        <Card className={classes.modal}>
          <header className={classes.header}>
            <h2>{props.title}</h2>
          </header>
          <div className={classes.content}>
            <p>{props.message}</p>
          </div>
          <footer className={classes.actions}>
            <Button onClick={props.onConfirm}>Okay</Button>
          </footer>
        </Card>
      );
    };
    const ErrorModal = (props) => {
      return (
        <React.Fragment>
          {ReactDOM.createPortal(
            <Backdrop onConfirm={props.onConfirm} />,
            document.getElementById("backdrop-root")
          )}
          {ReactDOM.createPortal(
            <ModalOverlay
              title={props.title}
              message={props.message}
              onConfirm={props.onConfirm}
            />,
            document.getElementById("overlay-root")
          )}
        </React.Fragment>
      );
    };
    
    export default ErrorModal;

     

    ๐ŸŽฏ ์™œ document.getElementById('portal-root') ์ด๋ ‡๊ฒŒ ์จ์ฃผ์–ด์•ผํ• ๊นŒ?

      {ReactDOM.createPortal(
            <Backdrop onConfirm={props.onConfirm} />,
            document.getElementById("backdrop-root")
      )}

    document.getElementById('portal-root')๋Š”

    ReactDOM.createPortal์—์„œ ์ž์‹ ์ปดํฌ๋„ŒํŠธ๋ฅผ ๋ Œ๋”๋งํ•  ๋Œ€์ƒ DOM ๋…ธ๋“œ๋ฅผ ์ง€์ •ํ•˜๋Š” ์—ญํ• ์„ ํ•จ.

     

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

     

Designed by Tistory.