모달 창 구현하기(react-modal)

이보아·2024년 7월 22일
0

1. React-modal 설치하기💻

react-modal 라이브러리를 설치한다.

npm install react-modal

2. CommonModal 컴포넌트 만들기🛠️

모달의 기본 구조를 만든다.

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;
  • Modal 컴포넌트를 사용해 모달의 기본 구조를 만든다.
  • isOpenonRequestClose props를 받아 모달의 열림/닫힘 상태를 관리한다.
  • button 태그를 만들어 닫기 버튼을 만들고, 아이콘을 추가한다.
  • 바깥 영역을 클릭할시 닫히는 기능을 구현하기위해 shouldCloseOnOverlayClick={true} 설정하고 바깥 영역을 커서를 손가락 모양으로 변경한다.( tailwind CSS: cursor-pointer 추가)

4. ContextProvider 컴포넌트 만들기🌐

모달을 열고 닫는 기능을 전역에서 사용할 수 있도록 관리한다. 이를 통해 애플리케이션의 어느 컴포넌트에서든지 모달을 쉽게 사용할 수 있다.

"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를 만들고, openModalcloseModal 함수를 정의한다.
  • useModal 훅을 통해 ModalContext를 사용할 수 있게 한다.
  • ContextProvider 컴포넌트는 모달의 내용을 관리하고, 모달을 열고 닫는 함수를 제공한다.

5. 모달 사용하기📚

모달이 필요한 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 함수가 호출되어 모달이 열린다.
profile
매일매일 틀깨기

0개의 댓글