Octocat

useMatchMedia

A hook that uses the matchMedia API to observe a media query

Source Code

import { useEffect, useState } from 'react';

export const useMatchMedia = (query: string, initialValue?: boolean) => {
  const [matches, setMatches] = useState(initialValue ?? false);

  useEffect(() => {
    const mediaQueryList = window.matchMedia(query);
    setMatches(mediaQueryList.matches);

    const handleChange = () => {
      setMatches(mediaQueryList.matches);
    };

    mediaQueryList.addEventListener('change', handleChange);

    return () => {
      mediaQueryList.removeEventListener('change', handleChange);
    };
  }, [query]);

  return matches;
};

Features

  • Media Query Support: Observe any CSS media query for responsive behavior
  • Real-time Updates: Automatically updates when the media query match changes

API Reference

Prop Default Type Description
query * - string The media query to observe
initialValue false boolean Initial value for the media query match

Examples

Basic Usage


          const Example = () => {
  const isLargeScreen = useMatchMedia("(min-width: 1024px)");
  const isLandscape = useMatchMedia("(orientation: landscape)");

  return (
    <div>
      {isLargeScreen && <p>Large screen detected!</p>}
      {isLandscape && <p>Landscape orientation!</p>}
    </div>
  );
};
        

Responsive Layout


          const ResponsiveLayout = () => {
  const isMobile = useMatchMedia("(max-width: 767px)");
  const isTablet = useMatchMedia("(min-width: 768px) and (max-width: 1023px)");
  const isDesktop = useMatchMedia("(min-width: 1024px)");

  return (
    <div>
      {isMobile && <MobileLayout />}
      {isTablet && <TabletLayout />}
      {isDesktop && <DesktopLayout />}
    </div>
  );
};
        

Accessibility Features


          const AccessibilityAware = () => {
  const prefersDark = useMatchMedia("(prefers-color-scheme: dark)");
  const prefersReducedMotion = useMatchMedia("(prefers-reduced-motion: reduce)");
  const isHighContrast = useMatchMedia("(prefers-contrast: high)");

  return (
    <div className={prefersDark ? "dark-theme" : "light-theme"}>
      {prefersReducedMotion && <p>Reduced motion enabled</p>}
      {isHighContrast && <p>High contrast mode active</p>}
    </div>
  );
};
        

Device Capabilities


          const DeviceAware = () => {
  const isHighDPI = useMatchMedia("(-webkit-min-device-pixel-ratio: 2), (min-resolution: 192dpi)");
  const isTouchDevice = useMatchMedia("(pointer: coarse)");
  const isHoverCapable = useMatchMedia("(hover: hover)");

  return (
    <div>
      {isHighDPI && <p>High DPI display detected</p>}
      {isTouchDevice && <p>Touch device detected</p>}
      {isHoverCapable && <p>Hover capable device</p>}
    </div>
  );
};
        

Previous

useIntersectionObserver

Next

useMousePan