mirror of
https://github.com/streamich/react-use.git
synced 2026-01-18 14:06:52 +00:00
50 lines
1.3 KiB
TypeScript
50 lines
1.3 KiB
TypeScript
import { useEffect, useState } from 'react';
|
|
import { isBrowser } from './misc/util';
|
|
|
|
const getInitialState = (query: string, defaultState?: boolean) => {
|
|
// Prevent a React hydration mismatch when a default value is provided by not defaulting to window.matchMedia(query).matches.
|
|
if (defaultState !== undefined) {
|
|
return defaultState;
|
|
}
|
|
|
|
if (isBrowser) {
|
|
return window.matchMedia(query).matches;
|
|
}
|
|
|
|
// A default value has not been provided, and you are rendering on the server, warn of a possible hydration mismatch when defaulting to false.
|
|
if (process.env.NODE_ENV !== 'production') {
|
|
console.warn(
|
|
'`useMedia` When server side rendering, defaultState should be defined to prevent a hydration mismatches.'
|
|
);
|
|
}
|
|
|
|
return false;
|
|
};
|
|
|
|
const useMedia = (query: string, defaultState?: boolean) => {
|
|
const [state, setState] = useState(getInitialState(query, defaultState));
|
|
|
|
useEffect(() => {
|
|
let mounted = true;
|
|
const mql = window.matchMedia(query);
|
|
const onChange = () => {
|
|
if (!mounted) {
|
|
return;
|
|
}
|
|
setState(!!mql.matches);
|
|
};
|
|
|
|
mql.addEventListener('change', onChange);
|
|
setState(mql.matches);
|
|
|
|
return () => {
|
|
mounted = false;
|
|
mql.removeEventListener('change', onChange);
|
|
};
|
|
}, [query]);
|
|
|
|
return state;
|
|
};
|
|
|
|
export default useMedia;
|