useIntersectionObserver
A React hook for observing element intersections using the Intersection Observer API
Installation
Props
Prop | Type | Default | Description |
---|---|---|---|
root | Element Document null | null | The element used as viewport for checking visibility. |
rootMargin | string | '0px' | Margin around the root when calculating intersections. |
threshold | number number[] | 0 | Percentage(s) of the target's visibility to trigger callback. |
Data
Property | Type | Description |
---|---|---|
ref | (node: T null) => void | Callback ref to assign to the target element. |
entry | IntersectionObserverEntry null | The latest observed intersection entry. |
isIntersecting | boolean | Whether the target is intersecting the root. |
Key Features & Details
Browser Support
The Intersection Observer API is widely supported across modern browsers:
- Chrome: Full support (v58+)
- Firefox: Full support (v55+)
- Safari: Full support (v12.1+)
- Edge: Full support (v16+)
- Opera: Full support (v45+)
Performance Considerations
- Offloads intersection detection to the browser for optimized performance.
- Automatically disconnects when ref is set to
null
or component unmounts. - Supports configurable thresholds and margins.
Best Practices & Caveats
- Always assign the returned
ref
to an element. - Use appropriate thresholds to avoid excessive callbacks.
- Consider debouncing when observing multiple elements.
- Clean up by setting
ref(null)
if you want to stop observing early. - Check for API support in older browsers or provide fallbacks.
Examples
Basic Usage
const { ref, entry, isIntersecting } =
useIntersectionObserver<HTMLDivElement>();
return <div ref={ref}>{isIntersecting ? 'Visible' : 'Not visible'}</div>;
With Custom Options
const { ref, entry, isIntersecting } = useIntersectionObserver<HTMLDivElement>({
root: document.querySelector('#scrollArea'),
rootMargin: '0px',
threshold: [0, 0.5, 1.0],
});
Reset Observer
<Button onClick={() => ref(null)}>Reset Observer</Button>
Usage
import { useIntersectionObserver } from '@/hooks/use-intersection-observer';
function MyComponent() {
const { ref, entry, isIntersecting } =
useIntersectionObserver<HTMLDivElement>({
threshold: 0.1,
});
return (
<div ref={ref}>
{isIntersecting ? 'In view' : 'Out of view'} (
{entry?.intersectionRatio.toFixed(2)})
</div>
);
}
Common Use Cases
- Lazy-loading images as they enter the viewport.
- Infinite scrolling pagination.
- Triggering animations when elements come into view.
- Reporting visibility of ads or analytics.
- Virtualizing long lists for performance.