Created
July 7, 2025 09:35
-
-
Save devheedoo/0db4d86dc821a741d2f95f341145c573 to your computer and use it in GitHub Desktop.
open/close modal using hash in React App
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import { useEffect, useState } from 'react' | |
import { useLocation, useNavigate } from 'react-router-dom' | |
export function useHashModal(hash: string) { | |
const location = useLocation() | |
const navigate = useNavigate() | |
const [isOpen, setIsOpen] = useState(location.hash === hash) | |
// 감시: 해시 바뀌면 열림/닫힘 상태 업데이트 | |
useEffect(() => { | |
setIsOpen(location.hash === hash) | |
}, [location.hash, hash]) | |
// 뒤로가기 등 브라우저 내비게이션 대응 | |
useEffect(() => { | |
const onPopState = () => { | |
setIsOpen(window.location.hash === hash) | |
} | |
window.addEventListener('popstate', onPopState) | |
return () => window.removeEventListener('popstate', onPopState) | |
}, [hash]) | |
const close = () => { | |
if (location.hash === hash) { | |
navigate(location.pathname, { replace: true }) | |
} | |
setIsOpen(false) | |
} | |
const forceOpen = () => { | |
const target = `${location.pathname}${hash}` | |
if (`${location.pathname}${location.hash}` === target) { | |
// 같은 해시면 강제 navigate로 React Router 리렌더 유도 | |
navigate('', { replace: true }) | |
setTimeout(() => { | |
navigate(target, { replace: false }) | |
}, 0) | |
} else { | |
navigate(target) | |
} | |
} | |
return { isOpen, close, forceOpen } | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment