Skip to content

Instantly share code, notes, and snippets.

@blacksmoke26
Last active April 14, 2023 22:28
Show Gist options
  • Star 3 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save blacksmoke26/65f35ee824674e00d858047e852bd270 to your computer and use it in GitHub Desktop.
Save blacksmoke26/65f35ee824674e00d858047e852bd270 to your computer and use it in GitHub Desktop.
React-bootstrap 'use-breakpoint' hook (flow)
// @flow
/**
* @author Junaid Atari
* @link https://github.com/blacksmoke26
* @since 2020-09-20
*/
// npm i -S debounce
import { useState, useEffect } from 'react';
import debounce from 'debounce';
export type Breakpoint = 'xs' | 'sm' | 'md' | 'lg' | 'xl' | 'xxl';
export const SIZE_XS: string = 'xs';
export const SIZE_SM: string = 'sm';
export const SIZE_MD: string = 'md';
export const SIZE_LG: string = 'lg';
export const SIZE_XL: string = 'xl';
export const SIZE_XXL: string = 'xxl';
const resolveBreakpoint = ( width: number ): Breakpoint => {
if ( width < 576 ) {
return SIZE_XS;
} else if ( width >= 576 && width < 768 ) {
return SIZE_SM;
} else if ( width >= 768 && width < 992 ) {
return SIZE_MD;
} else if ( width >= 992 && width < 1200 ) {
return SIZE_LG;
} else if ( width >= 1200 && width < 1440 ) {
return SIZE_XL;
} else if ( width >= 1440 ) {
return SIZE_XXL;
}
};
/** Get Media Query Breakpoints in React */
const useBreakpoint = (): Breakpoint => {
const [size, setSize] = useState(() => resolveBreakpoint(window.innerWidth));
useEffect(() => {
const calcInnerWidth = debounce(function () {
setSize(resolveBreakpoint(window.innerWidth));
}, 200);
window.addEventListener('resize', calcInnerWidth);
return () => window.removeEventListener('resize', calcInnerWidth);
}, []);
return size;
};
export default useBreakpoint;
@blacksmoke26
Copy link
Author

Vanilla JS version:

/**
 * @author Junaid Atari
 * @link https://github.com/blacksmoke26
 * @since 2020-09-20
 */

// npm i -S debounce

import { useState, useEffect } from 'react';
import debounce from 'debounce';

/**
 * @typedef {"xs" | "sm" | "md" | "lg" | "xl" | "xxl"} Breakpoint
 */

export const SIZE_XS = 'xs';
export const SIZE_SM = 'sm';
export const SIZE_MD = 'md';
export const SIZE_LG = 'lg';
export const SIZE_XL = 'xl';
export const SIZE_XXL = 'xxl';

/**
 * @param {number} width
 * @returns {Breakpoint}
 */
const resolveBreakpoint = ( width ) => {
	if ( width < 576 ) {
		return SIZE_XS;
	} else if ( width >= 576 && width < 768 ) {
		return SIZE_SM;
	} else if ( width >= 768 && width < 992 ) {
		return SIZE_MD;
	} else if ( width >= 992 && width < 1200 ) {
		return SIZE_LG;
	} else if ( width >= 1200 && width < 1440 ) {
		return SIZE_XL;
	} else if ( width >= 1440 ) {
		return SIZE_XXL;
	}
};

/**
 * @returns {Breakpoint}
 */
const useBreakpoint = () => {
	const [size, setSize] = useState(() => resolveBreakpoint(window.innerWidth));
	
	useEffect(() => {
		const calcInnerWidth = debounce(function () {
			setSize(resolveBreakpoint(window.innerWidth));
		}, 200);
		window.addEventListener('resize', calcInnerWidth);
		return () => window.removeEventListener('resize', calcInnerWidth);
	}, []);
	
	return size;
};

export default useBreakpoint;

@briantical
Copy link

Thanks

@kkrico
Copy link

kkrico commented Mar 5, 2022

Really usefull, ty.

@AgainPsychoX
Copy link

My adaptation to use with TypeScript and use-debounce package (React style).

/**
 * @author Junaid Atari
 * @link https://gist.github.com/blacksmoke26/65f35ee824674e00d858047e852bd270
 *
 * Modified by AgainPsychoX to use TypeScript and `use-debounce` package.
 */

import { useState, useEffect } from 'react';
import { useDebouncedCallback } from "use-debounce";

export type Breakpoint = 'xs' | 'sm' | 'md' | 'lg' | 'xl' | 'xxl';

const resolveBreakpoint = (width: number): Breakpoint => {
	if (width < 576)  return 'xs';
	if (width < 768)  return 'sm';
	if (width < 992)  return 'md';
	if (width < 1200) return 'lg';
	if (width < 1440) return 'xl';
	return 'xxl';
};

const useBreakpoint = () => {
	const [size, setSize] = useState(() => resolveBreakpoint(window.innerWidth));
	const update = useDebouncedCallback(() => {
		setSize(resolveBreakpoint(window.innerWidth));
	}, 200);

	useEffect(() => {
		window.addEventListener('resize', update);
		return () => window.removeEventListener('resize', update);
	}, [update]);

	return size;
};

export default useBreakpoint;

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment