React 모달창 닫기 - react modalchang dadgi

rect modal의 바깥 창을 눌렀을 때 닫히게 하는 방법이다. wrapper 를 사용하는 방법이 있고 ref 를 사용하는 방법이 있는데 ref를 사용했다.

import { useState, useRef, useEffect } from "react"; const MyComponent = () => { const [actionModal, setActionModal] = useState(false); const node = useRef(); useEffect(() => { const clickOutside = (e) => { // 모달이 열려 있고 모달의 바깥쪽을 눌렀을 때 창 닫기 if (actionModal && node.current && !node.current.contains(e.target)) { setActionModal(false); } }; document.addEventListener("mousedown", clickOutside); return () => { // Cleanup the event listener document.removeEventListener("mousedown", clickOutside); }; }, [actionModal]); return (<div ref={node}> <div className="flex shrink-0 pointer" onClick={() => setActionModal((pre) => !pre)} > <img src="/images/more_horiz_black_24dp.svg" /> </div> {actionModal ? ( <div style={{ position: "fixed", backgroundColor: "white", padding: "0.625rem", border: "1px solid grey", zIndex: 10, borderRadius: "4px", }} > <div className="p-10">action sheet</div> <div className="p-10">action sheet</div> <div className="p-10">action sheet</div> </div> ) : null} </div>) } export default MyModal;

React 모달창 닫기 - react modalchang dadgi

기능 위주로 정리된 글

구조

<button>열기</button>
<ModalBg>
	<Modal>
    	모달 내용
        <button>취소</button>
    </Modal>
</ModalBg>
  • 열기 버튼을 클릭하면 모달이 열린다.
  • 모달의 백그라운드나 취소 버튼을 클릭하면 모달이 닫힌다.

모달의 상태를 state를 통해 지정

모달이 열린 상태일 때는 modal statetrue로 하고 꺼진 상태일 때는 false로 할 거다.

const [modal, setModal] = useState(false);
  • 처음에는 열려있지 않기 때문에 기본값을 false로 지정.

열기

<button onClick={ () => setModal(true) }>모달 열기</button>
  • 열기 버튼이 클릭되면 setModal 함수를 통해서 truestate 업데이트

modal state값이 true일 때 모달 렌더 1

{
  modal === true 
  ?
  <ModalBg>
    <Modal>
      <p>모달창입니다.</p>
      <button>취소</button>
    </Modal>
  </ModalBg>
  :
  null
}
  • 삼항연산자를 통해서 modal state값이 true인 경우에는 모달을 렌더하고 아닌 경우에는 null를 렌더
  • null를 렌더하면 아무것도 나타나지 않는다.
  • 참고 리액트 공식문서-조건부렌더링

modal state값이 true일 때 모달 렌더 2

{
  modal &&
  <ModalBg>
    <Modal>
      <p>모달창입니다.</p>
      <button>취소</button>
    </Modal>
  </ModalBg>
}
  • 단축 평가 논리 계산법을 통해서 modal state값이 true인 경우에는 모달을 렌더.
  • modal state 가 false 인 경우에는 false, true일 때는 <ModalBg>생략/ModalBg>가 된다.
  • 단순히 값에 따라 보였다가 안보였다하는 상태만 변하는 경우라면 단축 평가 논리 계산법을 쓰는 게 더 간편하다.
  • 참고 단축 평가 논리 계산법

취소 버튼으로 모달 닫기

{
  modal == true 
  ?
  <ModalBg>
    <Modal>
      <p>모달창입니다.</p>
      <button onClick={ () => setModal(false) }>취소</button>
    </Modal>
  </ModalBg>
  :
  null
}
  • 열기 버튼이 클릭되면 setModal 함수를 통해서 falsestate 업데이트
  • modal state의 값이 true가 아니기 때문에 null이 렌더되면서 모달이 사라진다.

모달 백그라운드 클릭해서 모달 닫기

useRef를 이용해서 모달 백그라운드를 제어해줘야 한다.

  1. Ref 객체 만들기
const outside = useRef();	
  1. 접근하고 싶은 태그에 ref 속성을 준다. (ref 속성의 값으로 앞서 만든 객체를 준다)
<ModalBg
  ref={oustside}
>
  1. DOM 다루기
    current는 접근하고 싶은 DOM를 가리킨다.
outside.current // => ModalBg
  1. 적용하기
<ModalBg
  ref={oustside}
  onClick={ (e) => { if(e.target == outside.current) setModal(false) } }
>
  • 클릭한 요소가 oustside.current 가 맞다면 모달이 꺼진다.

전체 구조

import { useState, useRef } from "react";

const Page = () => {
  const [modal, setModal] = useState(false);
  const outside = useRef();
  
  return (
    <>
      <button onClick={ () => setModal(true) }>모달 열기</button>
      {
        modal &&
        <ModalBg 
          ref={outside} 
          onClick={ (e) => { if(e.target == outside.current) setModal(false) } }
        >
          <Modal>
            모달 내용
            <button onClick={ () => setModal(false) }>취소</button>
          </Modal>
        </ModalBg>
      }
    </>
  )

}

export default Page;