Media queries in React for responsive design with hook and component APIs
—
The Hook API provides programmatic media query detection using React hooks. This is perfect for conditional logic, state management, and dynamic behavior based on screen characteristics.
The primary hook for media query detection and response in React components.
/**
* React hook for media query detection and response
* @param settings - Media query configuration object or CSS query string
* @param device - Optional device property overrides for SSR/testing
* @param onChange - Optional callback fired when media query match state changes
* @returns Boolean indicating if the media query currently matches
*/
function useMediaQuery(
settings: MediaQuerySettings,
device?: MediaQueryMatchers,
onChange?: (matches: boolean) => void
): boolean;
type MediaQuerySettings = Partial<MediaQueryAllQueryable & { query?: string }>;Parameters:
settings: Media query configuration. Can use object properties (e.g., { minWidth: 768 }) or raw CSS query string (e.g., { query: "(min-width: 768px)" })device?: Optional device property overrides. Useful for server-side rendering or testing with specific device characteristicsonChange?: Optional callback function that receives the new match state when the media query result changesReturns: Boolean value indicating whether the media query currently matches
Usage Examples:
import React, { useState } from "react";
import { useMediaQuery } from "react-responsive";
// Basic usage with object properties
const BasicExample = () => {
const isDesktop = useMediaQuery({ minWidth: 1224 });
const isMobile = useMediaQuery({ maxWidth: 767 });
const isTablet = useMediaQuery({ minWidth: 768, maxWidth: 1023 });
return (
<div>
{isDesktop && <p>Desktop layout</p>}
{isTablet && <p>Tablet layout</p>}
{isMobile && <p>Mobile layout</p>}
</div>
);
};
// Usage with CSS query strings
const QueryStringExample = () => {
const isRetina = useMediaQuery({ query: "(min-resolution: 2dppx)" });
const isLandscape = useMediaQuery({ query: "(orientation: landscape)" });
return (
<div>
{isRetina && <p>High DPI display detected</p>}
{isLandscape && <p>Landscape orientation</p>}
</div>
);
};
// Usage with onChange callback
const CallbackExample = () => {
const [screenType, setScreenType] = useState("unknown");
const isDesktop = useMediaQuery(
{ minWidth: 1224 },
undefined,
(matches) => {
if (matches) setScreenType("desktop");
}
);
const isMobile = useMediaQuery(
{ maxWidth: 767 },
undefined,
(matches) => {
if (matches) setScreenType("mobile");
}
);
return <p>Current screen type: {screenType}</p>;
};
// Usage with device overrides (useful for SSR)
const SSRExample = () => {
const isDesktop = useMediaQuery(
{ minWidth: 1224 },
{ width: 1400 } // Force desktop width for SSR
);
return isDesktop ? <p>Desktop content</p> : <p>Mobile content</p>;
};Responsive Breakpoints:
import { useMediaQuery } from "react-responsive";
const useBreakpoints = () => {
const isMobile = useMediaQuery({ maxWidth: 767 });
const isTablet = useMediaQuery({ minWidth: 768, maxWidth: 1023 });
const isDesktop = useMediaQuery({ minWidth: 1024 });
return { isMobile, isTablet, isDesktop };
};Device Orientation:
const useOrientation = () => {
const isPortrait = useMediaQuery({ orientation: "portrait" });
const isLandscape = useMediaQuery({ orientation: "landscape" });
return { isPortrait, isLandscape };
};High DPI Displays:
const useHighDPI = () => {
const isRetina = useMediaQuery({ minResolution: "2dppx" });
const isHighRes = useMediaQuery({ minResolution: "192dpi" });
return { isRetina, isHighRes };
};Print Media:
const usePrintMedia = () => {
const isPrint = useMediaQuery({ type: "print" });
const isScreen = useMediaQuery({ type: "screen" });
return { isPrint, isScreen };
};Custom Hook Compositions:
// Create reusable responsive hooks
const useDesktopMediaQuery = () =>
useMediaQuery({ query: "(min-width: 1280px)" });
const useTabletAndBelowMediaQuery = () =>
useMediaQuery({ query: "(max-width: 1279px)" });
// Component using custom hooks
const ResponsiveComponent = () => {
const isDesktop = useDesktopMediaQuery();
const isTabletAndBelow = useTabletAndBelowMediaQuery();
return (
<div>
{isDesktop && <DesktopLayout />}
{isTabletAndBelow && <MobileLayout />}
</div>
);
};Dynamic Media Queries:
const DynamicExample = () => {
const [breakpoint, setBreakpoint] = useState(768);
const matches = useMediaQuery({ minWidth: breakpoint });
return (
<div>
<input
type="range"
min="320"
max="1920"
value={breakpoint}
onChange={(e) => setBreakpoint(Number(e.target.value))}
/>
<p>
Screen is {matches ? "wider" : "narrower"} than {breakpoint}px
</p>
</div>
);
};interface MediaQueryMatchers {
aspectRatio?: string;
deviceAspectRatio?: string;
height?: number | string;
deviceHeight?: number | string;
width?: number | string;
deviceWidth?: number | string;
color?: boolean;
colorIndex?: boolean;
monochrome?: boolean;
resolution?: number | string;
orientation?: "portrait" | "landscape";
scan?: "progressive" | "interlace";
type?: MediaQueryType;
}
interface MediaQueryAllQueryable extends MediaQueryFeatures, MediaQueryTypes {
// Complete interface with all possible media query properties
}
type MediaQuerySettings = Partial<MediaQueryAllQueryable & { query?: string }>;Install with Tessl CLI
npx tessl i tessl/npm-react-responsive