// hooks/useMediaQuery.ts import { useEffect, useState, useRef } from 'react' export function useMediaQuery(query: string) { const [matches, setMatches] = useState(() => { if (typeof window === 'undefined') return false return window.matchMedia(query).matches }) const isMountedRef = useRef(true) useEffect(() => { if (typeof window === 'undefined') return isMountedRef.current = true const media = window.matchMedia(query) const listener = (e: MediaQueryListEvent) => { if (isMountedRef.current) { setMatches(e.matches) } } // Defer state update to avoid synchronous setState in effect queueMicrotask(() => { if (isMountedRef.current) { setMatches(media.matches) } }) media.addEventListener('change', listener) return () => { isMountedRef.current = false media.removeEventListener('change', listener) } }, [query]) return matches }