useResponsiveValue

A responsive value hook based on the screen size, similar to CSS media queries.


✅ Features

  • Tailwind-style breakpoints
  • Dynamic values
  • Lightweight

📦 Usage

1const layout = useResponsiveValue({
2  base: 'column',
3  md: 'row',
4  lg: 'grid',
5})
6
7return <div className={`flex flex-${layout}`}></div>

📋 Source Code

This is the full implementation of useResponsiveValue

1import { useEffect, useState } from 'react'
2
3const breakpoints: Record<string, string> = {
4  sm: '(max-width: 640px)',
5  md: '(max-width: 768px)',
6  lg: '(max-width: 1024px)',
7  xl: '(max-width: 1280px)',
8}
9
10export function useResponsiveValue<T>(map: Partial<Record<keyof typeof breakpoints, T>>, defaultValue: T): T {
11  const [value, setValue] = useState(defaultValue)
12
13  useEffect(() => {
14    const queries = Object.entries(breakpoints).map(([key, query]) => ({
15      key,
16      mql: window.matchMedia(query),
17    }))
18
19    const update = () => {
20      for (const { key, mql } of queries) {
21        if (mql.matches && map[key as keyof typeof breakpoints] !== undefined) {
22          setValue(map[key as keyof typeof breakpoints]!)
23          return
24        }
25      }
26      setValue(defaultValue)
27    }
28
29    update()
30    queries.forEach(({ mql }) => mql.addEventListener('change', update))
31    return () => queries.forEach(({ mql }) => mql.removeEventListener('change', update))
32  }, [])
33
34  return value
35}
36