<aside> 💡 dropdown이 켜진 상태에서 배경 클릭시, dropdown이 다시 사라지게 하는 방법에 대해 정리해보자
</aside>
dropdown의 배경을 클릭 했을때, dropdown이 바로 사라지게 하는 기능을 구현해보자.
const Dropdown = ({closeHandler}) => {
const dropdownRef = useRef()
return (
<div ref={dropdownRef} tabIndex={0} onBlur={closeHandler}>
목록들...
</div>
)
}
const Parent = () => {
const [open, setOpen] = useState(false)
const closeHandler = () ={
setOpen(false)
}
return (
<div>
<Dropdown closeHandler={closeHandler}/>
</div>
)
}
일반적으로 우리가 만드는 modal은 overlay를 깔기 때문에 배경 클릭시, modal이 꺼지게 하는 부분은 쉬웠지만, dropdown의 경우, overlay가 새로 생성 되지 않기 때문에, 해당 방법은 적용불가 하다고 생각하고 배제했다.
dropdown창이 켜지고 다른 창을 클릭하게 되면, focus가 바뀌게 되니, onBlur이벤트를 적용 하면 되겠다고 생각했다. 하지만, div에는 focus가 되지 않는다는 것을 알게 되었고, 실패했다. (참고로, input이나 button의 경우 focus가 가능한 것이 default이다.)
아무리 생각해도 onBlur를 이용해야겠다고 생각했고, 그럴려면 div에 focus를 하게 하는 방법이 필요했다. 그래서 찾은 결과가 contentEditable 와 tabIndex 였다.
하지만, contentEditable 같은 경우, 사용하니 react에서 위험하다는 오류를 보내었고, 찾아보니, 거의 모든 컴포넌트가 연결되어 있는 React에서 사용자가 수정가능 할 수 있도록 하는 contentEditable는 위험하다고 판단하여 기각! (실제로 단순히 포커스기능을 추가하려고 하는 나의 의도와 맞지 않았다.)
tabIndex의 경우, 해당 요소가 포커스 가능하게 하면서 tab키를 사용하는 연속적인 탐색에서 어떤 순서에 위치할지 나타내는 속성인데, 내가 쓰고 싶은 목적과 딱 부합하였다.
tabIndex = -1을 하게 되면 키보드 tab으로는 접근 불가하지만, 마우스로 접근이 가능함을 의미하고, tabIndex ≥0일 경우, 0, 1, 2, 3...은 키보드 tab으로도 접근이 가능하며, tab을 눌렀을때 몇번만에 접근 가능 한지를 보여주는 순서를 나타내는 index이다.
하지만!, dropdown이 켜졌다고 해서 무조건 해당 div에 focus가 생기지 않았다. 그래서 useEffect를 이용하여, dropdownRef.current.focus()형식으로 포커스를 처음 부여하고, 나중에 onBlur가 됐을때, dropdown이 꺼지는 함수를 실행 시키도록 만들었다.