Skip to content

Instantly share code, notes, and snippets.

@vincentriemer
Created June 13, 2019 07:27
Show Gist options
  • Save vincentriemer/312ab11f8fe7bf84e211bef543ac2044 to your computer and use it in GitHub Desktop.
Save vincentriemer/312ab11f8fe7bf84e211bef543ac2044 to your computer and use it in GitHub Desktop.
React PixelRatio Context & Hook
// @flow
import * as React from "react";
const DEFAULT_PIXEL_RATIO = 1;
function processPixelRatio(input: ?number): number {
return input ?? DEFAULT_PIXEL_RATIO;
}
// matchMedia feature detection
const shouldListen = "matchMedia" in window;
const initialPixelRatio = processPixelRatio(window.devicePixelRatio);
const PixelRatioContext: React.Context<number> = React.createContext(
initialPixelRatio
);
type Props = { children: React.Node };
export const PixelRatioProvider = (props: Props) => {
const [ratio, updateRatio] = React.useState(initialPixelRatio);
const handleChange = React.useCallback(() => {
updateRatio(processPixelRatio(window.devicePixelRatio));
}, [updateRatio]);
React.useEffect(() => {
const mediaMatcher =
shouldListen &&
window.matchMedia(`screen and (resolution: ${ratio}dppx)`);
mediaMatcher && mediaMatcher.addListener(handleChange);
return () => {
mediaMatcher && mediaMatcher.removeListener(handleChange);
};
}, [handleChange, ratio]);
return (
<PixelRatioContext.Provider value={ratio}>
{props.children}
</PixelRatioContext.Provider>
);
};
export function usePixelRatio() {
return React.useContext(PixelRatioContext);
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment