Post

[React] 특정 영역 외 클릭 감지

셀렉트 박스 외 영역 클릭 시 포커스 해제

개인 포폴 작업 중, 셀렉트 박스 외 영역 클릭 시 셀렉트 박스 포커스가 해제되는 기능을 구현할 필요가 있었습니다.

개인 프로젝트

 

❌ useEffect만 사용하는 방법

처음 시도한 방법은 useEffect 안에 mouseup 이벤트 리스너를 사용하는 방식이었습니다. 어느 정도 기능이 구현되긴 했지만, 클릭 시 리액트가 여러 번 리렌더링 되어 다시 포커스 상태로 돌아가는 경우가 있었기 때문에, 다른 방법을 찾아볼 필요가 있었습니다.

 

🙆‍♂️useRef를 같이 사용하는 방법

그 다음 시도한 방법은 useRef를 같이 사용하는 방식입니다. 이 방식은 특정 영역을 감지하는 ref를 원하는 요소에 지정해서, 해당 영역 이외의 영역을 클릭했을 때 이벤트를 발생시키는 방식입니다.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
import { useRef, useEffect } from 'React';

function App() {
	// Ref 디폴트값 null로 지정
	const searchRef = useRef(null);
    
    useEffect(() => {
        // 특정 영역 외 클릭 시 발생하는 이벤트
    	function handleFocus(e) {
        	if (searchRef.current && !searchRef.current.contains(e.target)) {
            	// input 체크 해제
                document.getElementById('thisSelectBox').checked = false;
            }
        }
        
        // 이벤트 리스너에 handleFocus 함수 등록
        document.addEventListener("mouseup", handleFocus);
        return () => { document.removeEventListener("mouseup", handleFocus); }
    }, [searchRef]);
    
    return (
        <div className='selectbox_wrap'>
            <input type='checkbox' id='thisInput'/>
            {/* Ref를 지정할 요소 */}
            <label ref={searchRef} htmlFor='thisInput' id='thisSelectBox'>폰트 형식</label>
            <div className='thisOptions'>
                <span>고딕</span>
                <span>명조</span>
                <span>손글씨</span>
                <span>장식체</span>
            </div>
        </div>
    );
}

export default App;

 

구현한 결과물입니다. mouseup 이벤트 리스너는 마우스를 클릭한 후 마우스를 때는 시점에 이벤트를 발생시킵니다. 마우스를 클릭하는 순간 이벤트를 발생시키고 싶으면 mouseup => mousedown으로 바꿔주면 됩니다.

구현된 결과물

This post is licensed under CC BY 4.0 by the author.