JAVASCRIPT
Implement Lazy Loading & Animations with `useIntersectionObserver`
Master the `useIntersectionObserver` React hook to detect when elements enter or exit the viewport, enabling lazy loading, infinite scrolling, and dynamic animations.
import { useEffect, useState, useRef } from 'react';
function useIntersectionObserver(
elementRef,
{ threshold = 0, root = null, rootMargin = '0%' }
) {
const [entry, setEntry] = useState(null);
const observer = useRef();
useEffect(() => {
const node = elementRef?.current; // DOM Element
const hasIOSupport = typeof window !== 'undefined' && !!window.IntersectionObserver;
if (!hasIOSupport || !node) return;
// Disconnect existing observer if any
if (observer.current) {
observer.current.disconnect();
}
const observerCallback = ([newEntry]) => {
setEntry(newEntry);
};
observer.current = new IntersectionObserver(observerCallback, {
threshold,
root,
rootMargin,
});
observer.current.observe(node);
return () => {
if (observer.current) {
observer.current.disconnect();
}
};
}, [elementRef, JSON.stringify({ threshold, root, rootMargin })]); // Dependencies for re-running observer
return entry;
}
export default useIntersectionObserver;
// Example Usage:
// import React, { useRef } from 'react';
// function MyImageComponent({ src, alt }) {
// const imgRef = useRef();
// const entry = useIntersectionObserver(imgRef, { threshold: 0.1 });
// const isVisible = entry?.isIntersecting;
//
// return (
// <img
// ref={imgRef}
// src={isVisible ? src : 'placeholder.jpg'} // Load actual image when visible
// alt={alt}
// style={{ minHeight: '300px', width: '100%', backgroundColor: 'lightgray' }}
// />
// );
// }
How it works: The `useIntersectionObserver` hook leverages the browser's `IntersectionObserver` API to notify when a target element (referenced by `elementRef`) enters or exits the viewport, or crosses a specified intersection threshold. It returns an `IntersectionObserverEntry` object, allowing components to react to visibility changes, enabling features like lazy loading of images, infinite scrolling, or triggering animations when elements become visible, while properly cleaning up the observer on component unmount.