[React] 모달을 열고 취소버튼이나 백그라운드 클릭을 통해 끄기

JIAH·2022년 6월 10일
1

모달 기능 구현 썸네일

기능 위주로 정리된 글

구조

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


{
  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;
profile
일단 해버리는 사람 되기~~

0개의 댓글