Skip to content

Instantly share code, notes, and snippets.

@leodutra
Last active May 7, 2022 04:28
Show Gist options
  • Save leodutra/dd30a271d3b82841771e196b956ac0ce to your computer and use it in GitHub Desktop.
Save leodutra/dd30a271d3b82841771e196b956ac0ce to your computer and use it in GitHub Desktop.
useIntersection - Hook to simplify usage of Intersection Observer
import { MutableRefObject, useEffect, useRef, useState } from 'react'
export const useIntersection = (
ref: MutableRefObject<Element | null>,
options?: IntersectionObserverInit | null,
once = false
): boolean => {
const [isIntersecting, setIsIntersecting] = useState(false)
const observerRef = useRef<IntersectionObserver | null>(null)
const optionsRef = useRef<typeof options>()
if (!isEqual(optionsRef.current, options)) {
optionsRef.current = options
}
const unobserve = () => {
observerRef.current?.disconnect()
}
useEffect(() => {
const destroy = () => {
unobserve()
observerRef.current = null
}
observerRef.current = new IntersectionObserver(([entry]) => {
setIsIntersecting(entry.isIntersecting)
if (once && entry.isIntersecting) {
destroy()
}
}, optionsRef.current ?? undefined)
return destroy
}, [optionsRef.current, once])
useEffect(() => {
if (!ref.current) return
observerRef.current?.observe(ref.current)
return unobserve
}, [observerRef.current, ref.current])
return isIntersecting
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment