34 lines
1.3 KiB
JavaScript
34 lines
1.3 KiB
JavaScript
import { useState, useEffect } from 'react';
|
|
|
|
// https://usehooks.com/useMedia/
|
|
export default function useMedia(queries, values, defaultValue) {
|
|
// Array containing a media query list for each query
|
|
const mediaQueryLists = queries.map(q => window.matchMedia(q));
|
|
|
|
// Function that gets value based on matching media query
|
|
const getValue = () => {
|
|
// Get index of first media query that matches
|
|
const index = mediaQueryLists.findIndex(mql => mql.matches);
|
|
// Return related value or defaultValue if none
|
|
return typeof values[index] !== 'undefined' ? values[index] : defaultValue;
|
|
};
|
|
|
|
// State and setter for matched value
|
|
const [value, setValue] = useState(getValue);
|
|
|
|
useEffect(
|
|
() => {
|
|
// Event listener callback
|
|
// Note: By defining getValue outside of useEffect we ensure that it has ...
|
|
// ... current values of hook args (as this hook callback is created once on mount).
|
|
const handler = () => setValue(getValue);
|
|
// Set a listener for each media query with above handler as callback.
|
|
mediaQueryLists.forEach(mql => mql.addListener(handler));
|
|
// Remove listeners on cleanup
|
|
return () => mediaQueryLists.forEach(mql => mql.removeListener(handler));
|
|
},
|
|
[] // Empty array ensures effect is only run on mount and unmount
|
|
);
|
|
|
|
return value;
|
|
}
|