useClickAway
Hook은 특정 UI의 외부를 클릭했을 때 함수를 실행할 수 있게 해주는 Hook입니다. 예를들어 모달창이 활성화가 되어있는 상태에서 닫기버튼이 아닌 외부를 클릭하여 모달창을 닫고싶은 경우가 있을 수 있습니다. 이러한 경우 useClickAway
를 사용하면 이를 보다 쉽게 구현할 수 있는데 예제를 통해 useClickAway
의 기본구조와 사용법에 대해 알아보고 모달창을 닫는 기능을 구현해보도록 하겠습니다.useClickAway(ref, fn, ['click']);
useClickAway
의 기본형태는 위와 같으며 아래의 예제를 통해 자세한 용법에 대해 알아보겠습니다.import { useClickAway } from "react-use"; import { useRef } from "react"; const App = () => { const foo = () => { console.log("ref의 외부가 클릭되었습니다."); }; const ref = useRef(null); useClickAway(ref, foo, ['click']); return ( <div ref={ref} style={{ width: 100, height: 100, background: "pink", }} /> ); }; export default App;
App.jsx

예제는 위의 이미지와 같이 분홍박스 바깥부분을 클릭하면 콘솔창에 메시지가 출력 되고 분홍박스를 클릭하면 아무일도 일어나지 않는 간단한 예제입니다. 이를통해 알 수 있는 것은
useClickAway
의 첫 번째 인자에는 외부영역 이외의 요소를 가리키며 두 번째 인자에는 ref의 외부요소가 클릭되었을 때 실행 될 함수를 가리킵니다. 그리고 세 번째 인자에는 원하는 이벤트 종류를 넣게되는데 세 번째 인자를 생략할 경우 기본적으로 ‘click’ 이벤트시 트리거되도록 설정이 됩니다. useClickAway(ref, () => { console.log("ref의 외부요소가 클릭되었습니다."); });
또한 위의 예제처럼 두 번째 인자에서 바로 함수를 선언하여 사용할 수도 있습니다.지금까지
useClickAway
의 기본형태에 대해 알아보았으니 이어지는 예제에서 모달창을 닫는 기능을 구현해보도록 하겠습니다. import { useState } from "react"; const App = () => { const [onModal, setOnModal] = useState("none"); const Modal = () => { onModal ? setOnModal(false) : setOnModal("none"); }; return ( <> <button style={{ margin: 20, }} onClick={Modal} > 모달창을 띄워주세요! </button> <div style={{ display: onModal, position: "absolute", top: 10, background: "pink", width: 200, }} > <p style={{ textAlign: "center", }} > 모달창을 닫겠습니까? </p> <button onClick={Modal} style={{ width: 200 }}> 예 </button> </div> </> ); }; export default App;
App.jsx


예제와 같이 코드를 작성하면 위와 같이 모달창을 띄울 수 있는 버튼이 생성됩니다. 버튼을 누르게되면 모달창이 활성화가 되며 “예”를 누르면 모달창이 닫히게 됩니다. 현재의 상태에서는 모달창의 외부를 클릭하여도 모달창은 그대로 남아있는 것을 알 수 있는데 이는 사용자 편의성을 고려해보았을 때 약간은 불편하다고 생각이 들수도 있습니다. 따라서 모달창의 외부를 클릭하였을때에도 모달창이 닫힐 수 있게
useClickAway
를 활용하여 코드를 개선해보겠습니다.import { useClickAway } from "react-use"; import { useRef } from "react"; import { useState } from "react"; const App = () => { const ref = useRef(null); useClickAway(ref, () => { if (onModal === "none") { return; } setOnModal("none"); }); const [onModal, setOnModal] = useState("none"); const Modal = () => { onModal ? setOnModal(false) : setOnModal("none"); }; return ( <> <button style={{ margin: 20 }} onClick={Modal}> 모달창을 띄워주세요! </button> <div ref={ref} style={{ display: onModal, position: "absolute", top: 10, background: "pink", width: 200, }} > <p style={{ textAlign: "center", }} > 모달창을 닫겠습니까? </p> <button onClick={Modal} style={{ width: 200 }}> 예 </button> </div> </> ); }; export default App;
App.jsx
앞선 예제를 위와같이 변경해주면 모달창의 외부를 클릭하여도 모달창이 닫히는 것을 확인할 수 있습니다.
이처럼
useClickAway
를 활용하면 특정 UI의 외부요소가 클릭되었을 때 콜백 함수를 실행시킬 수 있으며 클릭 뿐만아니라 다양한 event를 적용할 수도 있습니다.