FrontendPro

63Implement useIntersectionObserver() for lazy loading

mediumAbout 35 minutesCodingreacthooksintersection-observerperformance

Problem

Implement useIntersectionObserver({ root = null, rootMargin = "0px", threshold = 0, freezeOnceVisible = false } = {}). It returns [ref, isIntersecting]:

  • ref is a callback ref to attach to the element to watch;
  • isIntersecting is true while the element is visible (according to the options).

With freezeOnceVisible: true, the hook stops observing after the element first becomes visible and stays true. That is exactly what lazy loading needs.

Then build LazyImage({ src, alt }): it renders an <img> without a src until it is about to scroll into view (use rootMargin: "200px"), then sets src.

function Gallery({ photos }) {
  return photos.map((p) => <LazyImage key={p.id} src={p.url} alt={p.title} />);
}

Requirements

  • Use one IntersectionObserver per hook instance and disconnect it on unmount.
  • Support the watched element changing (that is why ref is a callback ref).
  • Recreate the observer when the options change.

Try it yourself

Write your solution, run it, then submit to check it against the tests.

App.jsxReact + DOM

Step-by-step

A callback ref is a function React calls with the DOM node (and with null on unmount). Store the node with const [element, setElement] = useState(null) and return setElement as the ref. Because it is state, attaching a different element re-runs the effect.

Unlock the full solution

What's inside

  • Step-by-step
  • Approach
  • Solution
  • Complexity
  • Edge cases
  • Follow-up questions
  • Tests

Includes 2 code listings, 5 edge cases, 4 follow-up questions.

One-time payment by UPI, card or net banking. Launch price.

All 150 answersOne payment, yours forever