A hook that makes it easy to use a media query in React.
Sometimes it's useful to render a different version of a component on different media. For instance: a navigation component can have wildly different implementations for mobile and desktop. This hook gives you the power to use media queries to trigger this behavior.
yarn add @kaliber/use-media-query
Add the library to your compileWithBabel
array:
config/default.js
module.exports = {
kaliber: {
compileWithBabel: [/@kaliber\/use-media-query/]
}
}
To support older browsers you will need to add some polyfills. When polyfilling for IE11 using polyfill.io, you need:
matchMedia
MediaQueryList.prototype.addEventListener
MediaQueryList.prototype.removeEventListener
import { useMediaQuery } from '@kaliber/use-media-query'
function Component() {
const showDesktopNavigation = useMediaQuery('screen and (min-width: 48em)')
return (
<div className={styles.component}>
<header className={styles.header}>
{showDesktopNavigation
? <HeaderDesktop items={menuItems} />
: <HeaderMobile items={menuItems} />
}
</header>
</div>
)
}
Please do refer to the example in the /example
folder to see how you can avoid CLS and displaying the wrong menu for a frame.
useMediaQuery
only returns a non-null value after the first render, because the first render there's no information about the media query available yet. If you need a default value, you can add one using the nullish coalescing operator:
const showDesktopNavigation = useMediaQuery('screen and (min-width: 48em)') ?? true
If you want to display a waiting state while you wait for useMediaQuery
to update, you can explicitly test against null
:
function Component() {
const isViewportMd = useMediaQuery('screen and (min-width: 48em)')
const indeterminate = isViewportMd === null
return (
<div className={styles.component}>
<header className={cx(styles.header, indeterminate && styles.indeterminate)}>
{/* ... */}
</header>
</div>
)
}
This library is intended for internal use, we provide no support, use at your own risk. It does not import React, but expects it to be provided, which @kaliber/build can handle for you.
This library is not transpiled.