Overview
The useMatchMedia hook enables reactive responses to CSS media query changes in your React components. It returns a boolean indicating whether the current viewport matches the specified media query, updating automatically when the viewport changes.
Signature
const useMatchMedia = (query: string): boolean
Parameters
A CSS media query string (e.g., “(min-width: 768px)“)
Return Value
Returns a boolean indicating whether the media query currently matches.
Usage
Responsive Layout
import { useMatchMedia } from './hooks/use-match-media';
function ResponsiveLayout() {
const isMobile = useMatchMedia('(max-width: 768px)');
const isDesktop = useMatchMedia('(min-width: 1024px)');
return (
<div>
{isMobile && <MobileNavigation />}
{isDesktop && <DesktopSidebar />}
<MainContent />
</div>
);
}
Dark Mode Detection
import { useMatchMedia } from './hooks/use-match-media';
function ThemeProvider({ children }: { children: React.ReactNode }) {
const prefersDark = useMatchMedia('(prefers-color-scheme: dark)');
return (
<div className={prefersDark ? 'dark-theme' : 'light-theme'}>
{children}
</div>
);
}
Conditional Rendering
import { useMatchMedia } from './hooks/use-match-media';
function ImageGallery() {
const isTablet = useMatchMedia('(min-width: 768px) and (max-width: 1023px)');
const isMobile = useMatchMedia('(max-width: 767px)');
const columns = isMobile ? 1 : isTablet ? 2 : 3;
return (
<div style={{ gridTemplateColumns: `repeat(${columns}, 1fr)` }}>
{/* Gallery items */}
</div>
);
}
Orientation Detection
import { useMatchMedia } from './hooks/use-match-media';
function VideoPlayer() {
const isPortrait = useMatchMedia('(orientation: portrait)');
return (
<div className={isPortrait ? 'portrait-mode' : 'landscape-mode'}>
<video controls>
<source src="video.mp4" type="video/mp4" />
</video>
{isPortrait && <p>Rotate your device for a better experience</p>}
</div>
);
}
Multiple Breakpoints
import { useMatchMedia } from './hooks/use-match-media';
function AdaptiveComponent() {
const isXSmall = useMatchMedia('(max-width: 479px)');
const isSmall = useMatchMedia('(min-width: 480px) and (max-width: 767px)');
const isMedium = useMatchMedia('(min-width: 768px) and (max-width: 1023px)');
const isLarge = useMatchMedia('(min-width: 1024px)');
return (
<div>
{isXSmall && <ExtraSmallLayout />}
{isSmall && <SmallLayout />}
{isMedium && <MediumLayout />}
{isLarge && <LargeLayout />}
</div>
);
}
Use Cases
- Responsive Components: Render different layouts based on screen size
- Conditional Features: Enable/disable features based on device capabilities
- Performance Optimization: Load different assets for mobile vs desktop
- Accessibility: Detect user preferences like reduced motion or contrast
- Device Detection: Identify tablets, phones, or desktop devices
- Theme Detection: Respond to system dark/light mode preferences
// Screen sizes
const isMobile = useMatchMedia('(max-width: 767px)');
const isTablet = useMatchMedia('(min-width: 768px) and (max-width: 1023px)');
const isDesktop = useMatchMedia('(min-width: 1024px)');
// User preferences
const prefersDark = useMatchMedia('(prefers-color-scheme: dark)');
const prefersReducedMotion = useMatchMedia('(prefers-reduced-motion: reduce)');
const prefersHighContrast = useMatchMedia('(prefers-contrast: high)');
// Device capabilities
const hasHover = useMatchMedia('(hover: hover)');
const hasPointer = useMatchMedia('(pointer: fine)');
const isTouch = useMatchMedia('(pointer: coarse)');
// Display properties
const isRetina = useMatchMedia('(min-resolution: 2dppx)');
const isPortrait = useMatchMedia('(orientation: portrait)');
Implementation Details
- Uses the native
window.matchMedia() API for optimal performance
- Automatically adds and removes event listeners for media query changes
- Updates component state reactively when the query match status changes
- Initializes with the correct match state on mount
- Cleans up event listeners on unmount to prevent memory leaks
- Uses the
useWindow hook for safe window access
Browser Support
The hook relies on the matchMedia API, which is supported in all modern browsers. The event listener approach is also widely supported.