Custom React Hooks: useIntersectionObserver()

Custom React Hooks: useIntersectionObserver()

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


    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" }}>
          ? "Element is visible"
          : "Element is not visible - scroll down"}
      <div style={{ height: "800px" }} />
      <div ref={ref} style={{ height: "200px", background: "red" }} />

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!

Did you find this article valuable?

Support Krzysztof Kałamarski by becoming a sponsor. Any amount is appreciated!