Package Exports
- react-responsiveness
Readme
React Responsiveness
Extremely light (~1 kB
gzipped) plugin in terms of both size and runtime resource consumption.
I wanted something really easy to use, and as light as possible.
To be fair, I am a bit obsessed with both performance and ease of use. If curios, scroll down to "How it works".
Installation
yarn
yarn add react-responsiveness
npm
npm i react-responsiveness
Peer dependencies *
react@>=16.x
react-dom@>=16.x
jotai@>=1.x
* you need these deps in your project to use react-responsiveness
Demo
Usage
The default breakpoints value is set to Bootstrap 5's responsiveness breakpoints preset:
A) Setup listeners:
import { useReactResponsiveness } from "react-responsiveness";
function App() {
const { addListeners } = useReactResponsiveness();
React.useLayoutEffect(() => {
addListeners();
}, []);
// ...
}
Can be in any other component, but I recommend App as it's first to render. This only needs to be done once.
B) Use in any component:
import { useReactResponsiveness } from "react-responsiveness";
const { isMin, isMax, isOnly, currentInterval } = useReactResponsiveness()
return (<>
<div>Current interval {currentInterval}</div>
{isMin('sm') && (
<!-- @media (min-width: 576px) -->
<div>content...</div>
)}
{isMax('sm') && (
<!-- @media (max-width: 767.9px) -->
<div>content...</div>
)}
{isOnly('sm') && (
<!-- @media (min-width: 576px) and (max-width: 767.9px) -->
<div>content...</div>
)}
</>)
Important notes
- It is only required to call
addListeners
once per page/app.matches
andcurrentInterval
are shared state across all components using the hook. - The plugin uses
jotai
for sharing state across components (it's much like Recoil, except smaller). You need to installjotai
in your project (~6 kB
gzipped) to usereact-responsiveness
.
Using Breakpoint Library presets:
In App:
const { addListeners } = useReactResponsiveness();
React.useLayoutEffect(() => {
addListeners(Presets.Tailwind_CSS);
}, []);
All available presets:
Bootstrap_3
, Bootstrap_4
, Bootstrap_5
, Bulma
, Chakra
, Foundation
, Ionic
, Material_Design
, Materialize
, Material_UI
, Quasar
, Semantic_UI
, Skeleton
, Tailwind_CSS
, Windi_CSS
Notes:
- If you maintain a CSS framework (or use one often) and want its preset added, open an issue or a PR.
- If you spot any inconsistency in the presets (either my typo or some library update), please, let me know, I'll correct it.
Bespoke intervals:
In App:
const { addListeners } = useReactResponsiveness();
React.useLayoutEffect(() => {
addListeners({
small: 0,
medium: 777,
large: 1234
});
}, []);
... then, in any component, including App:
const { isOnly } = useReactResponsiveness()
return (<>
{isOnly('medium') && (
<!-- @media (min-width: 777px) and (max-width: 1233.9px) -->
<div>content...</div>
)}
</>)
How it works:
- uses the native
window.matchMedia(queryString)
and only reacts to changes in the query'smatches
value. It's the same API powering CSS media queries - listeners are placed on the
MediaQueryList
instances, meaning they are garbage collected as soon as the app is unmounted, without leaving bound events behind on<body>
orwindow
object - no global pollution
- only places listeners once and shares state across all components
- in terms of memory and/or CPU consumption, listening to
window.matchMadia
'change' events is a few hundred times lighter than using the "traditional"resize
event listener method