Skip to content

Commit

Permalink
fix: rewrite useBreakpoint (#862)
Browse files Browse the repository at this point in the history
  • Loading branch information
tremby authored Dec 5, 2020
1 parent 506a7ac commit 3947016
Show file tree
Hide file tree
Showing 5 changed files with 60 additions and 24 deletions.
6 changes: 4 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -275,9 +275,11 @@ only('md') => '@media (min-width: 768px) and (max-width: 991.98px) { ... }'
/**
* @param {function} up | down | between | only
*
* @return {boolean} is the target breakpoint
* @return {(boolean|null)} `true` if currently matching the given query,
* `false` if not, and `null` if unknown (such as
* during server-side rendering)
*/
useBreakpoint(up('md')) => boolean
useBreakpoint(up('md')) => boolean | null
```

## Other
Expand Down
2 changes: 1 addition & 1 deletion react-emotion/index.d.ts
Original file line number Diff line number Diff line change
@@ -1 +1 @@
export declare function useBreakpoint(breakpoint: Function): boolean;
export declare function useBreakpoint(breakpoint: Function): boolean | null;
37 changes: 27 additions & 10 deletions react-emotion/index.js
Original file line number Diff line number Diff line change
@@ -1,24 +1,41 @@
const { useState, useEffect } = require('react');
const { useState, useEffect, useCallback } = require('react');
const { useTheme } = require('@emotion/react');

const useBreakpoint = (breakpoint) => {
// Get the media query to match
const query = breakpoint({
theme: useTheme(),
}).replace(/^@media/, '');
}).replace(/^@media\s*/, '');

const mq = window.matchMedia(query);
const [isBreak, setIsBreak] = useState(mq.matches);
// Keep track of current media query match state;
// initialize this to the current match state if possible,
// or to null (to mean "indeterminate" if the `window` object isn't available)
const [isBreak, setIsBreak] = useState(
typeof window !== 'undefined' ? window.matchMedia(query).matches : null
);

// Handler for the media query change event
const handleChange = useCallback((event) => {
setIsBreak(event.matches);
}, []);

// Set up a media query matcher on mount and if the query changes
useEffect(() => {
const handleResize = () => {
setIsBreak(window.matchMedia(query).matches);
};
const mq = window.matchMedia(query);

window.addEventListener('resize', handleResize);
// Ensure the correct value is set in state as soon as possible
setIsBreak(mq.matches);

return () => window.removeEventListener('resize', handleResize);
}, [query]);
// Update the state whenever the media query match state changes
mq.addEventListener('change', handleChange);

// Clean up on unmount and if the query changes
return function cleanup() {
mq.removeEventListener('change', handleChange);
};
}, [query, handleChange]);

// Return the current match state
return isBreak;
};

Expand Down
2 changes: 1 addition & 1 deletion react-styled/index.d.ts
Original file line number Diff line number Diff line change
@@ -1 +1 @@
export declare function useBreakpoint(breakpoint: Function): boolean;
export declare function useBreakpoint(breakpoint: Function): boolean | null;
37 changes: 27 additions & 10 deletions react-styled/index.js
Original file line number Diff line number Diff line change
@@ -1,24 +1,41 @@
const { useState, useEffect } = require('react');
const { useState, useEffect, useCallback } = require('react');
const { useTheme } = require('styled-components');

const useBreakpoint = (breakpoint) => {
// Get the media query to match
const query = breakpoint({
theme: useTheme(),
}).replace(/^@media/, '');
}).replace(/^@media\s*/, '');

const mq = window.matchMedia(query);
const [isBreak, setIsBreak] = useState(mq.matches);
// Keep track of current media query match state;
// initialize this to the current match state if possible,
// or to null (to mean "indeterminate" if the `window` object isn't available)
const [isBreak, setIsBreak] = useState(
typeof window !== 'undefined' ? window.matchMedia(query).matches : null
);

// Handler for the media query change event
const handleChange = useCallback((event) => {
setIsBreak(event.matches);
}, []);

// Set up a media query matcher on mount and if the query changes
useEffect(() => {
const handleResize = () => {
setIsBreak(window.matchMedia(query).matches);
};
const mq = window.matchMedia(query);

window.addEventListener('resize', handleResize);
// Ensure the correct value is set in state as soon as possible
setIsBreak(mq.matches);

return () => window.removeEventListener('resize', handleResize);
}, [query]);
// Update the state whenever the media query match state changes
mq.addEventListener('change', handleChange);

// Clean up on unmount and if the query changes
return function cleanup() {
mq.removeEventListener('change', handleChange);
};
}, [query, handleChange]);

// Return the current match state
return isBreak;
};

Expand Down

0 comments on commit 3947016

Please sign in to comment.