← Back to all snippets
JAVASCRIPT

Detecting Element Visibility with React's useIntersectionObserver Hook

Create a custom `useIntersectionObserver` hook in React to efficiently detect when an element enters or exits the viewport, perfect for lazy loading and animations.

import { useEffect, useRef, useState } from 'react';

function useIntersectionObserver(ref, options) {
  const [isIntersecting, setIntersecting] = useState(false);
  const observer = useRef(null);

  useEffect(() => {
    if (!ref.current) return;

    // Ensure observer is reset if ref.current changes
    if (observer.current) {
      observer.current.disconnect();
    }

    observer.current = new IntersectionObserver(([entry]) => {
      setIntersecting(entry.isIntersecting);
    }, options);

    observer.current.observe(ref.current);

    return () => {
      if (observer.current) {
        observer.current.disconnect();
      }
    };
  }, [ref, options]); // Deep comparison for options might be needed if options object changes frequently

  return isIntersecting;
}

// Example Usage:
// function LazyImage({ src, alt }) {
//   const imgRef = useRef(null);
//   const isVisible = useIntersectionObserver(imgRef, {
//     root: null, // viewport
//     rootMargin: '0px',
//     threshold: 0.1, // 10% of element must be visible
//   });
//
//   return (
//     <img
//       ref={imgRef}
//       src={isVisible ? src : 'placeholder.jpg'} // Replace with a placeholder image
//       alt={alt}
//       style={{ minHeight: '300px', background: '#ccc' }} // For demonstration
//     />
//   );
// }
How it works: The `useIntersectionObserver` hook allows you to monitor an element (referenced by `ref`) for changes in its visibility relative to a parent element or the viewport. It uses the browser's `IntersectionObserver` API. The `useState` hook tracks whether the element is currently intersecting, and `useEffect` manages the observer's lifecycle, observing the target element and disconnecting when the component unmounts or dependencies change. This is invaluable for implementing lazy loading of images or components, infinite scrolling, or triggering animations when elements enter the viewport.

Need help integrating this into your project?

Our team of expert developers can help you build your custom application from scratch.

Hire DigitalCodeLabs