react-modal
라이브러리를 설치한다.
npm install react-modal
모달의 기본 구조를 만든다.
import React, { FC, ReactNode } from "react";
import Modal from "react-modal";
interface CommonModalProps {
isOpen: boolean;
onRequestClose: () => void;
children: ReactNode;
}
const CommonModal: FC<CommonModalProps> = ({ isOpen, onRequestClose, children }) => {
return (
<Modal
isOpen={isOpen} // 모달 열려있는지 여부 결정
onRequestClose={onRequestClose} // 모달 닫는 함수
shouldCloseOnOverlayClick={true} // 바깥 영역 클릭시 닫힘모드
className="flex items-center justify-center z-50"
overlayClassName="fixed inset-0 bg-black bg-opacity-50 flex items-center justify-center cursor-pointer"
contentLabel="모달"
>
<div className="relative bg-white rounded-lg p-8 max-w-lg mx-auto">
{/* 모달 닫기 버튼 */}
<button
onClick={onRequestClose}
className="absolute top-2 right-2 text-gray-500 hover:text-gray-700"
aria-label="모달 닫기 버튼"
>
<svg
xmlns="http://www.w3.org/2000/svg"
fill="none"
viewBox="0 0 24 24"
strokeWidth={2}
stroke="currentColor"
className="w-6 h-6"
>
<path strokeLinecap="round" strokeLinejoin="round" d="M6 18L18 6M6 6l12 12" />
</svg>
</button>
{children}
</div>
</Modal>
);
};
export default CommonModal;
isOpen
과 onRequestClose
props를 받아 모달의 열림/닫힘 상태를 관리한다.shouldCloseOnOverlayClick={true}
설정하고 바깥 영역을 커서를 손가락 모양으로 변경한다.( tailwind CSS: cursor-pointer 추가)모달을 열고 닫는 기능을 전역에서 사용할 수 있도록 관리한다. 이를 통해 애플리케이션의 어느 컴포넌트에서든지 모달을 쉽게 사용할 수 있다.
"use client";
import React, { createContext, useContext, useState, ReactNode, FC } from "react";
import CommonModal from "@/components/Common/Modal/CommonModal";
interface ModalContextType {
openModal: (content: ReactNode) => void;
closeModal: () => void;
}
interface ContextProviderProps {
children: ReactNode;
}
// 모달을 열고 닫는 함수의 Context 생성
const ModalContext = createContext<ModalContextType>({
openModal: () => {},
closeModal: () => {},
});
// useModal 훅을 사용하여 ModalContext를 사용할 수 있게 내보냄
export const useModal = () => useContext(ModalContext);
const ContextProvider: FC<ContextProviderProps> = ({ children }) => {
const [modalContent, setModalContent] = useState<ReactNode>(null); // 모달 안에 들어갈 내용을 저장
const [isModalOpen, setIsModalOpen] = useState(false); // 모달이 열려있는지 여부를 저장
const openModal = (content: ReactNode) => {
setModalContent(content); // 모달 내용을 설정
setIsModalOpen(true); // 모달 열기
};
const closeModal = () => {
setIsModalOpen(false); // 모달 닫기
setModalContent(null); // 모달 내용 초기화
};
return (
// ModalContext.Provider로 모달을 열고 닫는 함수를 제공
<ModalContext.Provider value={{ openModal, closeModal }}>
{children}
<CommonModal isOpen={isModalOpen} onRequestClose={closeModal}>
{modalContent}
</CommonModal>
</ModalContext.Provider>
);
};
export default ContextProvider;
ModalContext
를 만들고, openModal
과 closeModal
함수를 정의한다. useModal
훅을 통해 ModalContext
를 사용할 수 있게 한다.ContextProvider
컴포넌트는 모달의 내용을 관리하고, 모달을 열고 닫는 함수를 제공한다.모달이 필요한 page에 모달을 사용한다.
"use client";
import React from "react";
import { useModal } from "@/provider/ContextProvider";
const ModalTest: React.FC = () => {
const { openModal } = useModal();
const handleOpenModal = () => {
openModal(
<div>
<h2 className="pb-1">모달 제목</h2>
<p>모달 내용입니다.</p>
</div>,
);
};
return (
<div className="flex flex-col items-center justify-center w-full h-[calc(100vh-66px)]">
<h1 className="mb-3">모달 테스트</h1>
<button
onClick={handleOpenModal}
className="px-4 py-2 bg-black text-white font-semibold rounded-lg focus:outline-none"
>
모달 열기
</button>
</div>
);
};
export default ModalTest;
useModal
훅을 사용해 모달을 여는 openModal
함수를 가져온다.handleOpenModal
함수가 호출되어 모달이 열린다.