Last active
February 13, 2022 23:28
-
-
Save hrdtbs/476f022a07ff2a4550f3ddbfdc0c7e3a to your computer and use it in GitHub Desktop.
React hooks of Observers
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 { useLayoutEffect, useState } from "react" | |
let animationFrameID = 0 | |
export const useIntersectionObserver = ( | |
ref: React.RefObject<HTMLElement>, | |
options?: IntersectionObserverInit | |
): IntersectionObserverEntry | undefined => { | |
const [entry, setEntry] = useState<IntersectionObserverEntry>() | |
useLayoutEffect(() => { | |
const element = ref.current | |
const intersectionObserver = new IntersectionObserver(entries => { | |
if (!Array.isArray(entries)) { | |
return | |
} | |
if (!entries.length) { | |
return | |
} | |
animationFrameID = window.requestAnimationFrame(() => { | |
if (intersectionObserver) { | |
setEntry(entries[0]) | |
} | |
}) | |
}, options) | |
if (element) { | |
intersectionObserver.observe(element) | |
} | |
return () => { | |
if (element) { | |
intersectionObserver.unobserve(element) | |
} | |
window.cancelAnimationFrame(animationFrameID) | |
} | |
}, [options, ref]) | |
return entry | |
} |
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 { useLayoutEffect, useState } from "react" | |
const defaultConfig = { | |
childList: true | |
} | |
let animationFrameID = 0 | |
export const useMutationObserver = ( | |
ref: React.RefObject<HTMLElement>, | |
config: MutationObserverInit = defaultConfig | |
): MutationRecord | undefined => { | |
const [entry, setEntry] = useState<MutationRecord>() | |
useLayoutEffect(() => { | |
const element = ref.current | |
const mutationObserver = new MutationObserver(entries => { | |
if (!Array.isArray(entries)) { | |
return | |
} | |
if (!entries.length) { | |
return | |
} | |
animationFrameID = window.requestAnimationFrame(() => { | |
if (mutationObserver) { | |
setEntry(entries[0]) | |
} | |
}) | |
}) | |
if (element) { | |
mutationObserver.observe(element, config) | |
} | |
return () => { | |
if (element) { | |
mutationObserver.disconnect() | |
} | |
window.cancelAnimationFrame(animationFrameID) | |
} | |
}, [config, ref]) | |
return entry | |
} |
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 { useEffect, useState } from "react" | |
import ResizeObserver from "resize-observer-polyfill" | |
let animationFrameID = 0 | |
export const useResizeObserver = <T extends HTMLElement>(ref: React.RefObject<T>): ResizeObserverEntry | undefined => { | |
const [entry, setEntry] = useState<ResizeObserverEntry>() | |
useEffect(() => { | |
const element = ref.current | |
const resizeObserver = new ResizeObserver(entries => { | |
if (!Array.isArray(entries)) { | |
return | |
} | |
if (!entries.length) { | |
return | |
} | |
animationFrameID = window.requestAnimationFrame(() => { | |
if (resizeObserver) { | |
setEntry(entries[0]) | |
} | |
}) | |
}) | |
if (element) { | |
resizeObserver.observe(element) | |
} | |
return () => { | |
if (element) { | |
resizeObserver.unobserve(element) | |
} | |
window.cancelAnimationFrame(animationFrameID) | |
} | |
}, [ref]) | |
return entry | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment