DEV Community

Cover image for Utilizing Intersection Observer with Custom React Hook in TypeScript
Serif COLAKEL
Serif COLAKEL

Posted on

Utilizing Intersection Observer with Custom React Hook in TypeScript

Introduction:

In modern web development, creating responsive and dynamic user interfaces is crucial. One common requirement is to determine whether certain elements are within the viewport, enabling actions such as lazy loading of content or triggering animations. In this article, we'll explore how to achieve this using TypeScript and React, leveraging the Intersection Observer API through a custom React hook.

Understanding Intersection Observer:

Intersection Observer is a web API that allows developers to observe changes in the intersection between an element and its containing ancestor, or the viewport. This is particularly useful for scenarios where you need to know when an element becomes visible or hidden based on scrolling or other dynamic layout changes.

Creating a Custom React Hook:

We'll start by defining a custom React hook named useInViewPort, which encapsulates the logic for observing the intersection of a target element with the viewport. Here's the implementation:

import { useState, useEffect } from 'react';

function useInViewPort<T extends HTMLElement>(ref: React.RefObject<T>, options?: IntersectionObserverInit) {
  const [ inViewport, setInViewport ] = useState(false);

  useEffect(() => {
    const observer = new IntersectionObserver(([ entry ]) => {
      setInViewport(entry.isIntersecting);
    }, options);

    const currentRef = ref.current;

    if (currentRef) {
      observer.observe(currentRef);
    }

    return () => {
      if (currentRef) {
        observer.unobserve(currentRef);
      }
    };
  }, [ options, ref ]);

  return inViewport;
}

export default useInViewPort;
Enter fullscreen mode Exit fullscreen mode

Utilizing the Hook in a React Component:

Now, let's see how we can use this hook in a React component. Assume we have a div element that we want to observe:

import React, { useRef } from 'react';

import useInViewPort from './useInViewPort';

function MyComponent() {
  const targetRef = useRef<HTMLDivElement>(null);
  const inViewport = useInViewPort(targetRef, { threshold: 0.5 });

  return (
    <div>
      <div style={{ height: '1000px' }}>Scroll down</div>
      <div ref={targetRef} style={{ height: '200px', background: inViewport ? 'green' : 'red' }}>
        {inViewport ? 'In viewport' : 'Not in viewport'}
      </div>
    </div>
  );
}

export default MyComponent;
Enter fullscreen mode Exit fullscreen mode

In this example, we create a ref to the div element we want to observe (targetRef). We then use the useInViewport hook passing in this ref. The hook returns a boolean value (inViewport) indicating whether the element is currently in the viewport. We use this value to dynamically change the background color of the div based on its visibility.

Conclusion:

By creating a custom React hook that utilizes the Intersection Observer API, we've enabled a simple yet powerful way to track elements' visibility within the viewport in TypeScript-based React applications. This approach enhances the responsiveness and interactivity of web interfaces, opening doors to a wide range of possibilities such as lazy loading content, triggering animations, and optimizing performance. Experiment with this hook in your projects to unlock new ways of enhancing user experiences.

Top comments (0)