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 를 받아 사용"된다.
'React > React-Basic' 카테고리의 다른 글
6. className, style 다루기 (0) | 2022.12.12 |
---|---|
5. Context 다뤄보기 - 기본편 (0) | 2022.12.08 |
4. useReducer 바로 알기 - 기본편 (0) | 2022.12.08 |
3. useEffect 바로알기 with. 클린업 프로세스, 디바운싱 (0) | 2022.12.08 |
1. State 끌어올리기(상향식 컴포넌트 데이터 이동) (0) | 2022.12.07 |
댓글