hook made for listening to resize events ie use-on-resize.js, with a debounced callback as to make performance even better.

This commit is contained in:
Asad Umar 2022-01-28 20:42:02 +05:00 committed by Thomas Zarebczan
parent e4abc7ef41
commit b2093e822a
2 changed files with 12 additions and 28 deletions

View file

@ -8,6 +8,7 @@ import {
TabPanel as ReachTabPanel, TabPanel as ReachTabPanel,
} from '@reach/tabs'; } from '@reach/tabs';
import classnames from 'classnames'; import classnames from 'classnames';
import { useOnResize } from '../../effects/use-on-resize';
// Tabs are a compound component // Tabs are a compound component
// The components are used individually, but they will still interact and share state // The components are used individually, but they will still interact and share state
@ -45,22 +46,14 @@ function Tabs(props: TabsProps) {
const [tabsRect, setTabsRect] = React.useState(); const [tabsRect, setTabsRect] = React.useState();
// Create a ref of the parent element so we can measure the relative "left" for the bar for the child Tab's // Create a ref of the parent element so we can measure the relative "left" for the bar for the child Tab's
// Don't observe as its going to re-render when the window size changes anyway
const tabsRef = useRef<Element | void | null>(); const tabsRef = useRef<Element | void | null>();
function changeWindowSize() { // Recalculate "Rect" on window resize
useOnResize(() => {
if (tabsRef.current) { if (tabsRef.current) {
setTabsRect(tabsRef.current.getBoundingClientRect() || undefined); setTabsRect(tabsRef.current.getBoundingClientRect());
} }
} });
React.useEffect(() => {
window.addEventListener('resize', changeWindowSize);
return () => {
window.removeEventListener('resize', changeWindowSize);
};
}, []);
const tabLabels = props.children[0]; const tabLabels = props.children[0];
const tabContent = props.children[1]; const tabContent = props.children[1];
@ -107,22 +100,14 @@ function Tab(props: TabProps) {
const { isSelected } = props; const { isSelected } = props;
const [rect, setRect] = React.useState(); const [rect, setRect] = React.useState();
function changeWindowSize() { // Recalculate "Rect" on window resize
useOnResize(() => {
if (ref.current) { if (ref.current) {
setRect(ref.current.getBoundingClientRect() || undefined); setRect(ref.current.getBoundingClientRect());
} }
} });
React.useEffect(() => {
window.addEventListener('resize', changeWindowSize);
return () => {
window.removeEventListener('resize', changeWindowSize);
};
}, []);
// Each tab measures itself // Each tab measures itself
// Don't observe as its going to re-render when the window size changes anyway
const ref = useRef<Element | void | null>(); const ref = useRef<Element | void | null>();
// and calls up to the parent when it becomes selected // and calls up to the parent when it becomes selected

View file

@ -1,15 +1,14 @@
import { useEffect } from 'react'; import { useEffect } from 'react';
import debounce from 'util/debounce';
export function useOnResize(cb) { export function useOnResize(cb) {
useEffect(() => { useEffect(() => {
function handleResize() { const handleResize = debounce(cb, 100);
cb();
}
window.addEventListener('resize', handleResize); window.addEventListener('resize', handleResize);
handleResize(); handleResize();
return () => window.removeEventListener('resize', handleResize); return () => window.removeEventListener('resize', handleResize);
}, [cb]); }, []);
} }