-
-
Save ironyee/9498659b82e13ddb2d8db3279dafbb9c to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import { useCallback, useEffect, useRef, useState } from 'react'; | |
function debounce(callback: Function, delay = 300) { | |
let handle: number; | |
return function () { | |
if (handle) clearTimeout(handle); | |
handle = setTimeout(callback, delay); | |
}; | |
} | |
interface Size { | |
width: number; | |
height: number; | |
} | |
function isSizeChanged(s1?: Size, s2?: Size) { | |
if (s1 === s2) { | |
return false; | |
} | |
if (!s1 || !s2) { | |
return true; | |
} | |
return s1.width !== s2.width || s1.height !== s2.height; | |
} | |
function useDomSize(onResize: (width: number, height: number) => void) { | |
const ref = useRef<HTMLDivElement>(null); | |
const lastDomSize = useRef<Size | undefined>(undefined); | |
const handleResize = useCallback(() => { | |
const target = ref.current; | |
if (!target) { | |
return; | |
} | |
const oldSize = lastDomSize.current; | |
const newSize = { | |
width: target.clientWidth, | |
height: target.clientHeight, | |
}; | |
if (isSizeChanged(oldSize, newSize)) { | |
onResize(newSize.width, newSize.height); | |
} | |
lastDomSize.current = newSize; | |
}, [onResize]); | |
useEffect(() => { | |
handleResize(); | |
const debouncedHandler = debounce(handleResize); | |
window.addEventListener('resize', debouncedHandler); | |
return () => window.removeEventListener('resize', debouncedHandler); | |
}, [handleResize]); | |
return ref; | |
} | |
export default useDomSize; |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment