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

PropDefaultTypeDescription

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>
  );
};