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.

Need help integrating this into your project?

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

Hire DigitalCodeLabs