
React Hooks를 사용하여 컴포넌트 외부의 클릭 감지하기
React Hooks를 사용하고 특정 요소 외부에서 클릭이 발생했는지 확인해야 하는 경우, useRef 훅을 사용하여 요소에 대한 참조를 가져온 후 클릭 외부 감지 메커니즘을 구현할 수 있습니다. 이 블로그 포스트에서는 React Hooks를 사용하여 이러한 기능을 만드는 방법을 살펴보겠습니다.
useRef 훅
useRef 훅은 React의 내장 훅으로, 다시 렌더링되어도 유지되는 가변 값을 생성할 수 있습니다. 이는 특정 컴포넌트의 클릭 외부를 감지하는 경우와 같이 DOM 요소에 대한 참조를 가져오는 데 자주 사용됩니다.
다음은 코드 예시입니다:
import React, { useState, useEffect, useRef } from 'react';
import ReactDOM from 'react-dom';
const Menu = () => {
const wrapperRef = useRef(null);
const [isVisible, setIsVisible] = useState(true);
// componentDidMount와 componentDidUnmount와 같음
useEffect(() => {
document.addEventListener('click', handleClickOutside, true);
return () => {
document.removeEventListener('click', handleClickOutside, true);
};
}, []);
const handleClickOutside = event => {
const domNode = ReactDOM.findDOMNode(wrapperRef.current);
if (!domNode || !domNode.contains(event.target)) {
setIsVisible(false);
}
}
return(
<div ref={wrapperRef}>
Menu
</div>
)
}
export default Menu;
위에서는 Menu라는 함수형 컴포넌트를 정의합니다. 이 컴포넌트 내에서 useRef 훅을 사용하여 wrapperRef라는 변수를 정의합니다. 이 ref는 ref 속성을 사용하여 컴포넌트의 가장 바깥쪽 div 요소에 연결됩니다.
또한 메뉴의 가시성을 결정하는 isVisible이라는 상태 변수도 있습니다. 초기에는 true로 설정됩니다.
useEffect 훅에서는 클릭 이벤트를 감지하기 위해 document에 이벤트 리스너를 추가합니다. handleClickOutside 함수를 이벤트 핸들러로 전달하고 “useCapture” 매개변수를 true로 설정합니다. 이렇게 하면 이벤트가 버블링 단계가 아닌 캡처링 단계에서 캡처됩니다.
handleClickOutside 함수 내에서는 ReactDOM.findDOMNode를 사용하여 wrapperRef의 실제 DOM 노드를 찾습니다. 그런 다음 클릭된 대상이 wrapper DOM 노드 내에 포함되어 있는지 확인합니다. 포함되어 있지 않으면 setIsVisible 함수를 사용하여 메뉴의 가시성을 false로 설정합니다.
마지막으로 return 문에서는 컴포넌트의 JSX를 렌더링하며 wrapperRef를 가장 바깥쪽 div 요소에 연결합니다.
코드 개선하기
위의 코드 예제는 작동하지만 몇 가지 개선 사항이 있습니다.
1. 올바른 이벤트 매개변수 유형 사용하기
현재 코드에서는 handleClickOutside 함수에 일반적인 이벤트 매개변수를 사용합니다. 그러나 TypeScript에서 유형 검사 및 자동 완성 지원을 받으려면 MouseEvent 유형을 사용해야 합니다.
개선된 코드:
const handleClickOutside = (event: MouseEvent) => {
// 코드 내용 작성
}
2. useEffect 정리 코드 리팩토링하기
현재 useEffect 훅의 정리 함수는 이벤트 리스너를 올바르게 제거하지 않습니다. addEventListener 호출과 동일한 매개변수 대신 제거하려는 함수 참조를 exact하게 removeEventListener에 전달해야 합니다.
개선된 코드:
useEffect(() => {
const handleClickOutside = (event: MouseEvent) => {
// 코드 내용 작성
};
document.addEventListener('click', handleClickOutside, true);
return () => {
document.removeEventListener('click', handleClickOutside, true);
};
}, []);
결론
이 블로그 포스트에서는 React Hooks(특히 useRef 훅)를 사용하여 React 컴포넌트에서 클릭 외부를 감지하는 방법을 배웠습니다. ref를 사용하고 document에 이벤트 리스너를 추가함으로써 사용자가 컴포넌트의 DOM 트리 외부를 클릭한 경우를 확인할 수 있습니다. 또한, 올바른 이벤트 유형을 사용하고 useEffect 훅에서 이벤트 리스너를 올바르게 정리하는 등 코드의 개선 사항도 살펴보았습니다. 이 기능을 구현하는 것은 드롭다운 메뉴나 모달 같은 컴포넌트 외부를 클릭할 때 닫는 등의 작업을 처리해야 하는 시나리오에서 유용합니다.
React 프로젝트에서 이 코드를 구현할 때 필요한 종속성을 가져오고 올바른 구문 규칙을 따르는 것을 잊지 마세요. 이 지식을 통해 React Hooks를 사용하여 컴포넌트 외부의 클릭을 쉽게 감지할 수 있습니다!