React useIntersectionObserver Hook: Lazy Load & Detect Visibility (2026)

You want to load an image only when it scrolls near the viewport. Or fire an analytics event the first time a card is actually seen. Or trigger "load more" when the user reaches the bottom of a list. Every one of these is the same question — is this element on screen yet? — and for years the answer was a scroll listener that fired hundreds of times a second, re-read getBoundingClientRect() on each tick, and still managed to miss the edge cases.

IntersectionObserver is the browser API that answers that question correctly, asynchronously, and off the main thread. useIntersectionObserver is the hook that wires it into React without the useEffect/useRef/cleanup boilerplate — and without the leak-on-unmount and stale-closure bugs the hand-rolled version always ships. This post covers the real @reactuses/core API, the three patterns you'll actually reach for, and how to tune threshold, rootMargin, and root. SSR-safe and typed.

Why Not Just Use a Scroll Listener?

The old way to know whether an element was visible looked like this: listen to scroll, and on every event measure the element against the viewport.