언젠간 진화하겠지!

[React] 모달 영역 밖 클릭 시 모달 닫히게 하기 본문

Today I learned!/오늘 하루 배운 것, 기억할 것

[React] 모달 영역 밖 클릭 시 모달 닫히게 하기

sweeee 2023. 8. 2. 00:33

공부를 하던 중 모달 영역 밖 클릭 시 모달을 닫히게 하는 방법이 내가 쓰던 방법과 라는 방법이 있다는 걸 알게 되었다.

기존에 쓰던 방법은 아래와 같다. 

 

기존 방법

빈 div 태그에 onClick이벤트 활성화

const App=()=>{
	const [ModalOpen,setModalOpen]=useState(false)

return (
	<>
            <Contents/>
	    {modalOpen&&<Modal setModalOpen={setModalOpen} />})
	</>

)}

// 모달 컴포넌트
const Modal=({setModalOpen})=>{

return(
	<div className="modalWrapper">
		<div className="bg" onClick={()=>setModalOpen(prev=>!prev)}/>
		<ModalContent/>
	</div>)
}

css

.bg{
    position:fixed;
    top:0;
    right:0;
    bottom:0;
    left:0;
    /* top:0,right:0,bottom:0,left:0을 하면 화면 꽉차게 된다*/
    background-color:rgba(0,0,0,0.3);
}

css에 따라 다르겠지만,내용이 없는 빈 div를 하나 두고  그 요소로 화면을 꽉 차게 만든 후 div를 클릭할 시 click이벤트가 실행되어 닫히게 되는 그런 형태다. 장점이 있다면, ModalContent가 bg의 부모가 아니기 때문에 ModalContent컴포넌트의 CSS구조를 먼저 짜더라도 그다지 신경쓸 문제가 없다.

 

다른 방법

1. useRef사용하기

const Modal=({setModalOpen})=>{
    const ref= useRef()
    const clickOutSideHandler = (e) => {
        if (ref.current && !ref.current.contains(e.target) {
          setIsFocused(false);
    }
  };

return(
	<div className="modalWrapper" ref={ref} onClick={clickOutSideHandler}>
		<ModalContent/>
	</div>)
}
.modalWrapper{
    position:fixed;
    top:0;
    right:0;
    bottom:0;
    left:0;
    background-color:rgba(0,0,0,0.3);
}

ModalContent를 감싸고 있는 div를 useRef를 통해 ref로 지정해 놓는다. modalWrapper의 영역을 클릭했을때, modalWrapper의 자식 요소(ModalContent)를 클릭하지 않는다면 창이 닫히게 된다.

다만 이렇게 설정을 하게 된다면,자식요소인 ModalContent가 modalWrapper의 css요소를 상속 받게 된다. 그래서 조금 더 까다롭다고 느껴졌다. 

 

2.useRef+useEffect+DOM

이 방법은 아래의 참고자료에 나온 방법이다. 참고자료를 그대로 인용한다면

  useEffect(() => {
    const checkIfClickedOutside = e => {
      if (isMenuOpen && ref.current && !ref.current.contains(e.target)) {
        setIsMenuOpen(false)
      }
    }

    document.addEventListener("mousedown", checkIfClickedOutside)
    return () => {
      // Cleanup the event listener
      document.removeEventListener("mousedown", checkIfClickedOutside)
    }
  }, [isMenuOpen])

위와 다른 점이 있다면, wrapper 해당 요소에 click이벤트를 설정하는게 아니고, useEffect를 사용해 이벤트를 넣었다 삭제하는 방법이다. eventListener를 사용하는 코드라서 되도록이면 다른 방법을 찾고 싶었지만, 아쉽게도 다른 코드를 찾지는 못했다. 

 


참고자료

https://www.codingdeft.com/posts/react-on-click-outside/

 

How to detect click outside in a React component | CodingDeft.com

Tutorial on how to detect when clicked outside a component in React and to hide it when the user clicks outside it.

www.codingdeft.com

 

Comments