React
에서 제공하는 훅인 useRef
와 React dom
에서 제공하는
createPortal
을 사용하여 간단한 모달 창을 구현해보도록 하겠습니다.
// Modal.jsx
import { forwardRef, useImperativeHandle, useRef } from "react";
import { createPortal } from "react-dom";
const Modal = forwardRef(function Modal({ children }, ref) {
useImperativeHandle(ref, () => {
return {
open() {
dialog.current.showModal();
},
};
});
const dialog = useRef();
return createPortal(
<dialog className="backdrop:bg-stone-900/90" ref={dialog}>
{children}
<button onClick={() => dialog.current.close()}>모달닫기</button>
</dialog>,
document.getElementById("modal")
);
});
export default Modal;
forwardRef
는 부모 컴포넌트에서 내려주는 ref 프롭스를 받아옵니다.
useImperativeHandle
은 부모컴포넌트에서 open
함수를 사용했을 때 그 안의 로직인
dialog.current.showModal
을 호출하게 합니다.
createPortal
은 해당 모달이 선택한 id선택자의 내부에 렌더링될 수 있도록 합니다.
<!-- index.html -->
<body>
<div id="modal"></div>
<div id="root"></div>
<script type="module" src="/src/main.jsx"></script>
</body>
// Modal 컴포넌트의 부모컴포넌트
import { useRef } from "react";
import Modal from "./Modal";
export default function ModalParents() {
const ref = useRef();
return (
<section>
<Modal ref={ref}>
<p>안녕하세요</p>
<p>모달입니다</p>
</Modal>
<button onClick={() => ref.current.open()}>모달열기</button>
</section>
);
}