use-media
useMedia
React sensor hook that tracks state of a CSS media query.
Usage
With useEffect
import useMedia from 'use-media';// Alternatively, you can import as:// import {useMedia} from 'use-media'; const Demo = // Accepts an object of features to test const isWide = ; // Or a regular media query string const reduceMotion = ; return <div> Screen is wide: isWide ? '😃' : '😢' </div> ;;
With useLayoutEffect
import useMediaLayout from 'use-media'; const Demo = // Accepts an object of features to test const isWide = ; // Or a regular media query string const reduceMotion = ; return <div> Screen is wide: isWide ? '😃' : '😢' </div> ;;
Testing
Depending on your testing setup, you may need to mock window.matchMedia
on components that utilize the useMedia
hook. Below is an example of doing this in jest
:
/test-utilities/index.ts
import mockMediaQueryList from 'use-media/lib/useMedia';// Types are also exported for convienence:// import {Effect, MediaQueryObject} from 'use-media/lib/types'; { const mql: MediaQueryList = ...mockMediaQueryList media matches ; return mql;} { const mockedImplementation = ; windowmatchMedia = jest;}
/components/MyComponent/MyComponent.test.tsx
const mediaQueries = mobile: '(max-width: 767px)' prefersReducedMotion: '(prefers-reduced-motion: reduce)'; ;
Storing in Context
Depending on your app, you may be using the useMedia
hook to register many matchMedia
listeners across multiple components. It may help to elevate these listeners to Context
.
/components/MediaQueryProvider/MediaQueryProvider.tsx
import React createContext useContext useMemo from 'react';import useMedia from 'use-media'; interface Props children: ReactReactNode; const MediaQueryContext = ; const mediaQueries = mobile: '(max-width: 767px)' prefersReducedMotion: '(prefers-reduced-motion: reduce)'; { const mobileView = ; const prefersReducedMotion = ; const value = ; return <MediaQueryContext.Provider => children </MediaQueryContext.Provider> ;} { return ;}
/components/App/App.tsx
import React from 'react';import MediaQueryProvider from '../MediaQueryProvider';import MyComponent from '../MyComponent'; { return <MediaQueryProvider> <div ="MyApp"> <MyComponent /> </div> </MediaQueryProvider> ;}
/components/MyComponent/MyComponent.tsx
import React from 'react';import useMediaQueryContext from '../MediaQueryProvider'; { const mobileView prefersReducedMotion = ; return <div> <p>mobileView: </p> <p>prefersReducedMotion: </p> </div> ;}