← Back to all snippets
JAVASCRIPT

Detect Element Visibility with useIntersectionObserver

Create a useIntersectionObserver React hook to efficiently detect when a DOM element enters or exits the viewport, enabling lazy loading or scroll-based animations.

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

function useIntersectionObserver(options) {
  const [entry, setEntry] = useState(null);
  const targetRef = useRef(null);

  useEffect(() => {
    const currentRef = targetRef.current;
    if (!currentRef) return;

    const observer = new IntersectionObserver(([ent]) => {
      setEntry(ent);
    }, options);

    observer.observe(currentRef);

    return () => {
      observer.unobserve(currentRef);
    };
  }, [options]); // Re-run if options change, though often options are static

  return [targetRef, entry];
}
/*
// Example usage:
function LazyImage({ src, alt }) {
  const [imgRef, entry] = useIntersectionObserver({ threshold: 0.1 });
  const isVisible = entry?.isIntersecting;

  return (
    <img
      ref={imgRef}
      src={isVisible ? src : undefined}
      alt={alt}
      style={{ minHeight: '200px', background: 'lightgray', transition: 'opacity 0.5s', opacity: isVisible ? 1 : 0.5 }}
    />
  );
}

// To use LazyImage in a component:
// function MyGallery() {
//   return (
//     <div style={{ height: '200vh', overflowY: 'scroll' }}>
//       <h2>Scroll down to see images load!</h2>
//       <div style={{ height: '80vh' }}></div>
//       <LazyImage src="https://via.placeholder.com/150/FF0000/FFFFFF?text=Image+1" alt="Placeholder Image 1" />
//       <div style={{ height: '80vh' }}></div>
//       <LazyImage src="https://via.placeholder.com/150/0000FF/FFFFFF?text=Image+2" alt="Placeholder Image 2" />
//     </div>
//   );
// }
*/
How it works: This useIntersectionObserver hook provides a way to detect when a component (or any DOM element) enters or leaves the viewport. It returns a `ref` to attach to the target element and an `entry` object from the Intersection Observer API. The `entry.isIntersecting` property can then be used to determine visibility. This is highly efficient for implementing features like lazy loading images, infinite scrolling, or triggering animations when elements become visible.

Need help integrating this into your project?

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

Hire DigitalCodeLabs