Skip to content

Instantly share code, notes, and snippets.

@udittyagi
Last active June 12, 2021 13:58
Show Gist options
  • Save udittyagi/466e7b6a11f1fec438035cf04339c7e7 to your computer and use it in GitHub Desktop.
Save udittyagi/466e7b6a11f1fec438035cf04339c7e7 to your computer and use it in GitHub Desktop.
import React, {
useState,
useEffect,
createContext,
useContext} from 'react';
const defaultValue = {}
const BreakpointContext = createContext(defaultValue);
const BreakpointProvider = ({children, queries}) => {
const [queryMatch, setQueryMatch] = useState({});
useEffect(() => {
const mediaQueryLists = {};
const keys = Object.keys(queries);
let isAttached = false;
const handleQueryListener = () => {
const updatedMatches = keys.reduce((acc, media) => {
acc[media] = !!(mediaQueryLists[media] && mediaQueryLists[media].matches);
return acc;
}, {})
setQueryMatch(updatedMatches)
}
if (window && window.matchMedia) {
const matches = {};
keys.forEach(media => {
if (typeof queries[media] === 'string') {
mediaQueryLists[media] = window.matchMedia(queries[media]);
matches[media] = mediaQueryLists[media].matches
} else {
matches[media] = false
}
});
setQueryMatch(matches);
isAttached = true;
keys.forEach(media => {
if(typeof queries[media] === 'string') {
mediaQueryLists[media].addListener(handleQueryListener)
}
});
}
return () => {
if(isAttached) {
keys.forEach(media => {
if(typeof queries[media] === 'string') {
mediaQueryLists[media].removeListener(handleQueryListener)
}
});
}
}
}, [queries]);
return (
<BreakpointContext.Provider value={queryMatch}>
{children}
</BreakpointContext.Provider>
)
}
function useBreakpoint() {
const context = useContext(BreakpointContext);
if(context === defaultValue) {
throw new Error('useBreakpoint must be used within BreakpointProvider');
}
return context;
}
export {useBreakpoint, BreakpointProvider};
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment