useMediaQuery()

Easily retrieve media dimensions with this Hook React which also works onResize.

Note:

Before Safari 14, MediaQueryList is based on EventTarget and only supports addListener/removeListener for media queries. If you don't support these versions you may remove these checks. Read more about this on MDN.

The Hook

1import { useEffect, useState } from 'react'
2
3function useMediaQuery(query: string): boolean {
4 const getMatches = (query: string): boolean => {
5 // Prevents SSR issues
6 if (typeof window !== 'undefined') {
7 return window.matchMedia(query).matches
8 }
9 return false
10 }
11
12 const [matches, setMatches] = useState<boolean>(getMatches(query))
13
14 function handleChange() {
15 setMatches(getMatches(query))
16 }
17
18 useEffect(() => {
19 const matchMedia = window.matchMedia(query)
20
21 // Triggered at the first client-side load and if query changes
22 handleChange()
23
24 // Listen matchMedia
25 if (matchMedia.addListener) {
26 matchMedia.addListener(handleChange)
27 } else {
28 matchMedia.addEventListener('change', handleChange)
29 }
30
31 return () => {
32 if (matchMedia.removeListener) {
33 matchMedia.removeListener(handleChange)
34 } else {
35 matchMedia.removeEventListener('change', handleChange)
36 }
37 }
38 // eslint-disable-next-line react-hooks/exhaustive-deps
39 }, [query])
40
41 return matches
42}
43
44export default useMediaQuery

Usage

1import React from 'react'
2
3import { useMediaQuery } from 'usehooks-ts'
4
5export default function Component() {
6 const matches = useMediaQuery('(min-width: 768px)')
7
8 return (
9 <div>
10 {`The view port is ${matches ? 'at least' : 'less than'} 768 pixels wide`}
11 </div>
12 )
13}

Edit on CodeSandbox

See a way to make this page better?
Edit there »