Skip to content

Commit

Permalink
feat: add useMediaLayout hook
Browse files Browse the repository at this point in the history
Adds `useMediaLayout` hook that internally uses `useLayoutEffect` React hook.
  • Loading branch information
streamich authored Mar 13, 2019
2 parents 067d575 + 6bf101f commit 6b04735
Show file tree
Hide file tree
Showing 2 changed files with 30 additions and 3 deletions.
21 changes: 21 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,8 @@

## Usage

With `useEffect`

```jsx
import {useMedia} from 'use-media';

Expand All @@ -21,3 +23,22 @@ const Demo = () => {
);
};
```

With `useLayoutEffect`

```jsx
import {useMediaLayout} from 'use-media';

const Demo = () => {
// Accepts an object of features to test
const isWide = useMediaLayout({ minWidth: 1000 });
// Or a regular media query string
const reduceMotion = useMediaLayout('(prefers-reduced-motion: reduce)');

return (
<div>
Screen is wide: {isWide ? '😃' : '😢'}
</div>
);
};
```
12 changes: 9 additions & 3 deletions src/index.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import { DependencyList, EffectCallback } from 'react';
import * as React from 'react';

const { useState, useEffect } = React;
const { useState, useEffect, useLayoutEffect } = React;

type MediaQueryObject = { [key: string]: string | number | boolean };

Expand All @@ -23,13 +24,14 @@ const objectToString = (query: string | MediaQueryObject) => {
.join(' and ');
};

export const useMedia = (
type Effect = (effect: EffectCallback, deps?: DependencyList) => void;
const createUseMedia = (effect: Effect) => (
rawQuery: string | MediaQueryObject,
defaultState: boolean = false
) => {
const [state, setState] = useState(defaultState);
const query = objectToString(rawQuery);
useEffect(() => {
effect(() => {
let mounted = true;
const mql = window.matchMedia(query);
const onChange = () => {
Expand All @@ -49,4 +51,8 @@ export const useMedia = (
return state;
};


export const useMedia = createUseMedia(useEffect);
export const useMediaLayout = createUseMedia(useLayoutEffect);

export default useMedia;

0 comments on commit 6b04735

Please sign in to comment.