DEV Community

HidetoshiYanagisawa
HidetoshiYanagisawa

Posted on

Harnessing the Power of React with IntersectionObserver!

https://dev-to-uploads.s3.amazonaws.com/uploads/articles/gyuvf27gpsfn7xyunuch.png

The IntersectionObserver API, which observes whether an element is within the viewport, can supercharge your user experience when combined with React. In this article, we'll dive deep into unlocking its full potential!

Table of Contents

  1. What is IntersectionObserver?
  2. Basics of Using IntersectionObserver in React
  3. Practical Application: 3 Powerful Features
    • Lazy Loading
    • Infinity Scroll
    • Ad Visibility Measurement
  4. Conclusion

What is IntersectionObserver?

IntersectionObserver is an API designed to monitor when specific elements enter or exit the viewport. This allows for effective control of element visibility and triggering certain actions based on their state.

Basics of Using IntersectionObserver in React

To utilize IntersectionObserver within React, we primarily combine useRef and useEffect. We capture DOM elements with useRef and then set up the observer within the useEffect.

Practical Application: 3 Powerful Features

1. Lazy Loading

Lazy Loading is a technique where elements (especially images and videos) are not loaded immediately on page load, but only when needed—like when scrolling brings them close to the viewport.

Code Sample

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

function LazyImage({ src, alt, ...props }) {
  const [isLoaded, setIsLoaded] = useState(false);
  const imgRef = useRef(null);

  useEffect(() => {
    const observer = new IntersectionObserver(([entry]) => {
      if (entry.isIntersecting) {
        imgRef.current.src = src;
        imgRef.current.onload = () => setIsLoaded(true);
        observer.disconnect();
      }
    });

    observer.observe(imgRef.current);

    return () => observer.disconnect();
  }, [src]);

  return <img ref={imgRef} alt={alt} {...props} style={isLoaded ? {} : { opacity: 0 }} />;
}
Enter fullscreen mode Exit fullscreen mode

Explanation

  • We manage the image's loading state using useState.
  • We hold a reference to the image element using useRef.
  • Within the useEffect, we set up an observer to monitor if the element enters the viewport.
  • Upon entering, we set the actual src, initiating the image load.

2. Infinity Scroll

A technique where, upon reaching the bottom of the page, more content is automatically loaded. Commonly seen on social media platforms.

Code Sample

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

function InfinityScroll({ fetchData }) {
  const [items, setItems] = useState([]);
  const loadingRef = useRef(null);

  useEffect(() => {
    const observer = new IntersectionObserver(async ([entry]) => {
      if (entry.isIntersecting) {
        const newItems = await fetchData();
        setItems(prevItems => [...prevItems, ...newItems]);
      }
    });

    if (loadingRef.current) {
      observer.observe(loadingRef.current);
    }

    return () => observer.disconnect();
  }, [fetchData]);

  return (
    <div>
      {items.map(item => (
        <div key={item.id}>{item.name}</div>
      ))}
      <div ref={loadingRef}>Loading...</div>
    </div>
  );
}
Enter fullscreen mode Exit fullscreen mode

Explanation

  • We observe a loading status element.
  • When this element comes into view, we fetch more data and append it to our existing item list.

3. Ad Visibility Measurement

Measuring the duration an advertisement remains visible in the viewport. This can be crucial for billing criteria in ad platforms.

Code Sample

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

function AdComponent({ src }) {
  const adRef = useRef(null);
  const startTimeRef = useRef(null);

  useEffect(() => {
    const observer = new IntersectionObserver(([entry]) => {
      if (entry.isIntersecting) {
        startTimeRef.current = new Date();
      } else if (startTimeRef.current) {
        const duration = new Date() - startTimeRef.current;
        console.log(`Ad was visible for ${duration}ms`);
        startTimeRef.current = null;
      }
    });

    if (adRef.current) {
      observer.observe(adRef.current);
    }

    return () => observer.disconnect();
  }, []);

  return <img ref={adRef} src={src} alt="Advertisement" />;
}
Enter fullscreen mode Exit fullscreen mode

Explanation

  • We record the time an ad becomes visible.
  • When the ad exits the viewport, we compute the visibility duration and log it.

Conclusion

Combining React with IntersectionObserver allows for the easy implementation of extremely powerful features. Use the examples above as a guide and integrate them into your projects for an enhanced user experience!

Top comments (0)