useRef를 이용한 이벤트리스너

mangorovski·2022년 11월 16일
0

dom을 직접 선택해야 하는 경우들이 있다.
1. 엘리먼트의 크기를 가져와야 할 때
2. 스크롤바 위치를 가져와야 할 때
3. 엘리먼트에 포커스를 설정 해줘야 할 때
등등

모달 창 외의 부분을 클릭하게 되면 창이 닫히는 이벤트를 만들어 줄것이다.
(먼저 modal div에 ref를 설정해준 상태이다)

//main.js

const ref = useRef()
useOnClickOutside(ref, () => { setModalOpen(false) })

함수를 하나 만들자.
useOnclickOutside()함수는 ref와 콜백함수를 매개변수로 받고 있다.

import React, { useEffect } from 'react'

export const useOnClickOutside = (ref, handler) => {
    useEffect(() => {
        const listener = (event) => {
            if (!ref.current || ref.current.contains(event.target)) {
                return
            } else {
                handler()
            }
        }
        document.addEventListener("mousedown", listener) 
        document.addEventListener("touchstart", listener)

        return () => {
            document.addEventListener("mousedown", listener)
            document.addEventListener("touchstart", listener)

        };
    }, [ref, handler])
}

왜 useEffect를 했을까?

  • ref.current의 변화(모달 창 의 안인지? 밖인지?)가 있는것을 감지하고 이벤트를 실행해야 한다.
  • 모달 창의 밖을 클릭한게 맞다면? 콜백 함수를 실행해 줄 것이다.

listener의 함수를 살펴보자.
!ref.current : event가 발생했는데 ref가 없을 때
ref.current.contains(event.target): 이벤트의 타겟을 ref가 포함하고 있을 때

(모달 창 안의 내용을 클릭할 때) 이럴 때는 그냥 return을 해준다.

그렇지 않을 경우 handler함수로 이용해 setModatl(false)로 모달 창을 닫아 준다.


[useEffect에서 mount, unMount]

useEffect안에서 마운트가 됐던 컴포넌트의 listner는
return을 통해서 unMount(clear)를 해줘야 한다.

document.addEventListener("mousedown", listener) 
document.addEventListener("touchstart", listener)
profile
비니로그 쳌킨

0개의 댓글