본문 바로가기
  • 삽질하는 자의 블로그
React/React-Basic

2. React Portal 사용해보기

by 이게뭐당가 2022. 12. 7.

1) 기존의 Modal 

        1. 모달을 만든다.
        2. 사용할 곳에서, modal 을 띄우거나, 제거하는 함수를 만든다.
        3. 모달 컴포넌트로 함수 포인터를 넘겨, 그곳에서도, 띄우거나, 제거할 수 있게 만든다.

< Modal 사용할 곳> =============================================

                import { useState } from "react";
                import Modal from "./components/UI/Modal";

                export default function App() {
                    const [modal, setModal] = useState(false);
                   
                   function toggleModal() {
                        setModal((prev) => !prev);
                    }

                    return (
                        <div className="App">
                            <button onClick={toggleModal}> 모달 띄우기</button>
                           {modal && <Modal closeModal={toggleModal} />}

                            ...

< Modal > =============================================

                import styles from "./Modal.module.css";

                function Modal(props) {
                   const { closeModal } = props;

                    return (
                        <div className={styles.modal}>
                           <div className={styles.backDrop} onClick={closeModal}></div>
                           <div className={styles.modalContent} onClick={closeModal}>
                                <h1> 이것은 Modal</h1>
                                <h2> 모달이 띄워졌습니다. 아무곳이나 눌러 제거하세요</h2>
                            </div>
                        </div>
                    );
                }
                export default Modal;



    2) 포탈을 사용한 Modal

        1. 모달을 만든다.
        2. 모달을 만들때, 한 컴포넌트 함수에 전부 넣지 말고, "한 파일"에 "여러 컴포넌트 함수"를 만들어, "분리시킨다."
 
        3. index.html 파일에, "modal 용 root" 를 만든다. (id로 DOM 에 접근해 안착시키므로, id 를 잘 적어준다.)
 
        4. "react-dom"에 접근하여 하여, "createPortal()" 메서드를 import 한다
        5. "createPortal()" 을 사용하여, "modal 용 root" 에서 "렌더되게 만든다".

        6. props 는 "실행하는곳"  >>    "Modal"    >>  "Modal 안의 여러 컴포넌트" 로 props drilling 한다.



        < index.html > ======================================================================

                ...
            <body>
                <noscript>You need to enable JavaScript to run this app.</noscript>
                <div id="root-modal-backdrop"></div>
                <div id="root-modal-content"></div>
                <div id="root"></div>
            </body>
            </html>

        < Modal 사용 할 곳> ======================================================================
       
            import { useState } from "react";
            import Modal from "./components/UI/Modal";

            export default function App() {
                const [modal, setModal] = useState(false);
               
                   function toggleModal() {
                    setModal((prev) => !prev);
                }

                return (
                    <div className="App">
                        <button onClick={toggleModal}> 모달 띄우기</button>
                       {modal && <Modal closeModal={toggleModal} />}

                        ...


        < Modal > ======================================================================

                import styles from "./Modal.module.css";
                import { createPortal } from "react-dom";                                   // createPortal 을 import

                function ModalBackDrop(props) {                                             // 각각의 파트를 분리 (선택사항)
                    const { closeModal } = props;                                                // 하단의 "Modal" 에서 온 props
 
                    return <div className={styles.backDrop} onClick={closeModal}></div>;
                }

                function ModalContent(props) {                                               // 각각의 파트를 분리 (선택사항)
                    const { closeModal } = props;                                               // 하단의 "Modal" 에서 온 props
 
                    return (
                        <div className={styles.modalContent} onClick={closeModal}>
                            <h1> 이것은 Modal</h1>
                            <h2> 모달이 띄워졌습니다. 아무곳이나 눌러 제거하세요</h2>
                        </div>
                    );
                }

                function Modal(props) {                                                          // Modal 은 렌더되어, portal 을 열어준다.
                    const { closeModal } = props;                                             // 사용한 곳에서 온  props

                    return (
                        <div>
                            {createPortal( <ModalBackDrop closeModal={closeModal} /> ,
                                                                    document.getElementById("root-modal-backdrop") )}
 
                             {createPortal( <ModalContent closeModal={closeModal} /> ,
                                                                     document.getElementById("root-modal-content") )}
                        </div>
                    );
                }

                export default Modal;
 
 
======================================================================================
 
 
    [총 정리]
 
      1.포탈의 장점  :  똑같이 실행시키는데, 내가 원하는 위치에서 실행 시킬 수 있다.
      2. 결국 포털될 컴포넌트를 사용하는 곳에서는, 포탈이 있으나 없으나 같다. 
      3. 다만, 포탈을 사용해, 팝업되는 컴포넌트는, 자신의 위치에 포털을 생성해, 원하는 위치에서 생성되는것이다.
 
 
 
            ==> [createPortal] 은, [첫번째 인자]로, 렌더될  "컴포넌트 함수(렌더 된 형태)"를 받고,
                                                [두번째 인자]로,  "컴포넌트를 렌더할 장소(실제 DOM 에 접근)" 를 받는다.

            ==> "App.js 에서, Modal 을 실행시키면", "Modal" 은 각 파트(혹은 뭉쳐진 하나의 파트)를 "portal" 하여
                              , index.html 의 root div 에서 실행시킨다".

            ==> "props"는 "App.js 에서 Modal 에만 전달"했으므로, "ModalContent""ModalBackDrop"
                               , "Modal 에서 props 를 받아 사용"된다.

 

댓글