230105 항해99 60일차 Modal

요니링 컴터 공부즁·2023년 1월 11일
0

모달창 구현 방법

  1. state 로 Modal 노출 여부를 관리한다.
  • useState 훅으로 모달창 노출 여부를 관리해준다.
// 모달을 노출시키는 페이지 컴포넌트
import { useState } from 'react';
import ModalBasic from '../src/common/ModalBasic';

// 모달을 노출하는 페이지
function Modal() {
    // 모달창 노출 여부 state
    const [modalOpen, setModalOpen] = useState(false);

    // 모달창 노출
    const showModal = () => {
        setModalOpen(true);
    };

    return (
        <div>
            <button onClick={showModal}>모달 띄우기</button>
            {modalOpen && <ModalBasic setModalOpen={setModalOpen} />}
        </div>
    );
}

export default Modal;
// 모달창 컴포넌트
import styles from './ModalBasic.module.css';

function ModalBasic({ setModalOpen, id, title, content, writer }: PropsType) {
    // 모달 끄기 
    const closeModal = () => {
        setModalOpen(false);
    };

    return (
        <div className={styles.container}>
            <button className={styles.close} onClick={closeModal}>
                X
            </button>
            <p>모달창입니다.</p>
        </div>
    );
}
export default ModalBasic;
  1. Modal 창이 최상위에 노출되도록 CSS를 조정한다.
  • position: absolute로 위치를 조정한다.
  • z-index를 높게 줘서 최상위에 노출 시킨다.
/* 모달창을 화면 중앙. 최상단에 노출 */
.container {
  /* 모달창 크기 */
  width: 300px;
  height: 200px;

  /* 최상단 위치 */
  z-index: 999;
  
  /* 중앙 배치 */
  /* top, bottom, left, right 는 브라우저 기준으로 작동한다. */
  /* translate는 본인의 크기 기준으로 작동한다. */
  position: absolute;
  top: 50%;
  left: 50%;
  transform: translate(-50%, -50%);

  /* 모달창 디자인 */
  background-color: gray;
  border: 1px solid black;
  border-radius: 8px;
}

/* 모달창 내부 X버튼 */
.close {
  position: absolute;
  right: 10px;
  top: 10px;
}
  1. 모달창 외부 클릭시, 모달창 제거 처리해준다.
  • 모달창 외부 document 클릭 이벤트를 달아준다.
import { useEffect, useRef } from 'react';
import styles from './ModalBasic.module.css';

function ModalBasic({ setModalOpen, id, title, content, writer }: PropsType) {

    // 모달 끄기 (X버튼 onClick 이벤트 핸들러)
    const closeModal = () => {
        setModalOpen(false);
    };

    // 모달 외부 클릭시 끄기 처리
    // Modal 창을 useRef로 취득
    const modalRef = useRef<HTMLDivElement>(null);
    
    useEffect(() => {
        // 이벤트 핸들러 함수
        const handler = () => {
            // mousedown 이벤트가 발생한 영역이 모달창이 아닐 때, 모달창 제거 처리
            if (modalRef.current && !modalRef.current.contains(event.target)) {
                setModalOpen(false);
            }
        };
        
        // 이벤트 핸들러 등록
        document.addEventListener('mousedown', handler);
        // document.addEventListener('touchstart', handler); // 모바일 대응
        
        return () => {
            // 이벤트 핸들러 해제
            document.removeEventListener('mousedown', handler);
            // document.removeEventListener('touchstart', handler); // 모바일 대응
        };
    });
    
    return (
        // 모달창을 useRef로 잡아준다.
        <div ref={modalRef} className={styles.container}>
            <button className={styles.close} onClick={closeModal}>
                X
            </button>
            <p>모달창입니다.</p>
        </div>
    );
}
export default ModalBasic;

참조:
[React] 모달창(Modal) 초간단 구현 방법(리덕스, 라이브러리 X)

0개의 댓글