ํ์ํํด ๋ฒํผ์ ๋๋ ์ ๋, ๋ชจ๋ฌ์ด ์ด๋ฆฌ์๋ง์ ๊ณง๋ฐ๋ก ๋ซํ๋ฒ๋ฆฌ๋ ๋ฌธ์ ๊ฐ ๋ฐ์ํ๋ค.
์ฌ์ง์ด Modal ์ปดํฌ๋ํธ ๋ด๋ถ์์ ํด๋ฆญํ ๊ฑด๋ฐ๋ onClose()๊ฐ ํธ์ถ๋๋ฉฐ ์ฌ๋ผ์ก๋ค.
๋ชจ๋ฌ ์ปดํฌ๋ํธ ๋ด๋ถ ์ฝ๋์์ ๋ค์๊ณผ ๊ฐ์ ๋ก์ง์ด ์์๋ค:
document.addEventListener('click', handleClick, true);
handleClick์ ์ด๋ ๊ฒ ๋์ํ๋ค:
const handleClick = (e: MouseEvent) => {
if (modalRef.current && !modalRef.current.contains(e.target as Node)) {
onClose();
}
};
์ฆ, ๋ชจ๋ฌ ๋ด๋ถ๊ฐ ์๋๋ผ๋ฉด ๋ฌด์กฐ๊ฑด ๋ซ์๋ฒ๋ฆฌ๋ ๊ตฌ์กฐ์๋๋ฐโฆ
๐ป ๋ฌธ์ ๋ ์ฌ๊ธฐ ์์๋ค:
modalRef.current ๋ฐ๊นฅ์ผ๋ก ์ธ์๋๋ ๊ฒฝ์ฐโ ๋ด๋ถ ํด๋ฆญ์ด์ด๋ "์ธ๋ถ ํด๋ฆญ"์ผ๋ก ์คํดํ๊ณ ๋ซ์๋ฒ๋ฆผ
console.log(e.target) ์ฐ์ด์ ๋ญ ๋๋ ๋์ง ํ์ธmodalRef.current.contains(e.target)์์ false ๋์ค๋ ์์๋ค ๋ถ์๊ฒฐ๊ตญ, ๋ฒํผ์ด๋ ํ ์คํธ๋ ref๊ฐ ์ฐธ์กฐํ ์๋ฆฌ๋จผํธ ์์ ์์ด ๋ณด์ด๋ ๊ฒ์ฒ๋ผ ์๋ํ ์ ์๋ค๋ ๊ฑธ ํ์ธํจ.
<div ref={modalRef} data-ignore-outside-click className="...">
handleClick()์์ ์ด ์์ฑ์ด ์๋์ง ๊ฒ์ฌ:const handleClick = (e: MouseEvent) => {
const target = e.target as HTMLElement;
if (target.closest('[data-ignore-outside-click]')) return;
if (modalRef.current && !modalRef.current.contains(target)) {
onClose();
}
};
๐ ์ด๋ก์จ data-ignore-outside-click ์์ฑ์ด ๋ชจ๋ฌ ๋ด๋ถ์์ ๋ช
์ํ๋ ๋ฐฉํจ ์ญํ ์ ํ๊ฒ ๋จ.
useRef().current.contains(e.target)๋ง์ผ๋ก๋ ๋ชจ๋ ๋ด๋ถ ํด๋ฆญ์ ์์ ํ๊ฒ ๋ณด์ฅํ์ง ๋ชปํ๋ค.closest('[data-ignore-outside-click]') ๊ฐ์ ์ปค์คํ
์์ฑ์ผ๋ก ํด๋ฆญ ํํฐ๋ฅผ ๋ช
ํํ๊ฒ ๊ฑธ์ด์ฃผ๋ ๊ฒ ๋ ์์ ์ .React์์ document.addEventListener(..., true)์ฒ๋ผ ์บก์ฒ๋ง ๋จ๊ณ๋ก ์ด๋ฒคํธ๋ฅผ ์ก๋ ๊ฑด ๋ชจ๋ฌ ์ธ๋ถ ํด๋ฆญ ๊ฐ์ง์๋ ํจ๊ณผ์ ์ด์ง๋ง,
์ฐ์ ์์ ์ถฉ๋์ด๋ ๋ฒ๋ธ๋ง ๋ฐฉํด ๋ฌธ์ ๋ ๋ฐ์ํ ์ ์์ผ๋ฏ๋ก ์ ์คํ ์จ์ผ ํ๋ค.