JAVASCRIPT
Detecting Element Visibility with `useIntersectionObserver`
Create a custom `useIntersectionObserver` React hook to efficiently detect when a DOM element enters or exits the viewport, ideal for lazy loading and animations.
import { useRef, useState, useEffect } from 'react';
function useIntersectionObserver(options) {
const [entry, setEntry] = useState(null); // Stores the IntersectionObserverEntry
const targetRef = useRef(null); // Ref to the DOM element to observe
useEffect(() => {
const node = targetRef.current; // The DOM element to observe
if (!node) return; // Don't do anything if no element is attached
// Create a new Intersection Observer instance
const observer = new IntersectionObserver(([ent]) => {
setEntry(ent); // Update state with the latest entry
}, options);
// Start observing the target element
observer.observe(node);
// Cleanup function: Disconnect observer when component unmounts or target changes
return () => {
observer.disconnect();
};
}, [options]); // Re-create observer if options change
return [targetRef, entry];
}
// Example Usage:
/*
function LazyLoadImage({ src, alt }) {
const [imgRef, entry] = useIntersectionObserver({ threshold: 0.1 });
const isVisible = entry?.isIntersecting;
return (
<div ref={imgRef} style={{ minHeight: '300px', border: '1px solid gray', display: 'flex', alignItems: 'center', justifyContent: 'center' }}>
{isVisible ? (
<img src={src} alt={alt} style={{ maxWidth: '100%', maxHeight: '100%' }} />
) : (
<p>Scroll to reveal image...</p>
)}
</div>
);
}
*/
How it works: The `useIntersectionObserver` hook provides a way to detect when a given DOM element (referenced by `targetRef`) enters or exits the viewport. It initializes an `IntersectionObserver` instance within a `useEffect` hook. When the observed element's intersection status changes, the observer's callback updates the `entry` state with the latest `IntersectionObserverEntry`. The hook returns both the `targetRef` (which you attach to the DOM element you want to observe) and the `entry` object, allowing you to react to the element's visibility, for example, to implement lazy loading or trigger animations.