Skip to main content

Command Palette

Search for a command to run...

Custom React Hooks: useIntersectionObserver()

Published
2 min read
Custom React Hooks: useIntersectionObserver()
K

🚀 CTO & Co-founder at Techfinity Studio — AI-driven software studio 👨‍💻 Full-stack developer, technical leader For the past 11 years, I’ve been building modern software solutions — today as the CTO and co-founder of Techfinity Studio, where we help companies build smart, efficient, and secure digital products. We use the right mix of technologies — from custom software to AI-driven solutions and low-code platforms — to deliver real business value. 💡 Key areas of expertise: • TypeScript, React, Next.js, Node.js, NestJS • AI integration & AI-driven apps • Security-first architecture • Functional Programming I’m passionate about building great software and helping organizations navigate the rapidly evolving tech landscape. Outside of work, I enjoy ♟️ playing chess and exploring the intersection of technology and creativity. 🌍 I work in an international environment. Languages: 🇵🇱 Polish (native) 🇬🇧 English (fluent) 🇪🇸 Spanish (fluent) 🇵🇹 Portuguese (good) 🇧🇬 Bulgarian (communicative) 🤝 If you’d like to connect to discuss: • building modern digital products • applying AI where it makes sense • designing secure and scalable architecture • or simply exchange ideas on technology Feel free to reach out!

Intersection Observer API lets programmers check if a DOM element is currently visible (i.e. intersecting) on the screen.

It can be used to:

  • display floating menu
  • lazy load images
  • perform animations
  • detect if ads are displayed
  • implement infinite scrolling

But now, let's focus on how to use it in React.

If you are like me, a lazy programmer, probably you are not interested in learning the theory. However, if that's not true, you can learn more about how to use this API in the MDN Web Docs.

So, let's see the code - here is copy-paste ready version of the hook:

useIntersectionObserver hook

// useIntersectionObserver.ts

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

const useIntersectionObserver = (ref: React.RefObject<HTMLElement>) => {
  const [state, setState] = useState<IntersectionObserverEntry>()

  useEffect(() => {
    if (!ref.current) return

    const observer = new IntersectionObserver(([elementState]) => setState(elementState), {
      root: null,
      rootMargin: '0px',
      threshold: 0
    })

    observer.observe(ref.current)

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

  return state
}

export default useIntersectionObserver

It's not that complicated! Let's see how to use it.

// Component.tsx

import React, { useRef } from "react";
import useIntersectionObserver from "./useIntersectionObserver";

const Component = () => {
  const ref = useRef<HTMLDivElement>(null);
  const intersection = useIntersectionObserver(ref);

  return (
    <section style={{ position: "relative" }}>
      <div style={{ position: "fixed" }}>
        {intersection?.isIntersecting
          ? "Element is visible"
          : "Element is not visible - scroll down"}
      </div>
      <div style={{ height: "800px" }} />
      <div ref={ref} style={{ height: "200px", background: "red" }} />
    </section>
  );
};

export default Component;

You can edit the working example on CodeSandbox: Edit useIntersectionObserver-example

I hope you find it useful. Stay tuned for more copy-paste ready custom react hook posts!