Skip to content

useOnScreen

React hook to monitor whether a referenced element is visible on the screen.

Add the hook via the CLI:

sh
npx @novajslabs/cli add useOnScreen
sh
npx @novajslabs/cli add useOnScreen
sh
pnpm dlx @novajslabs/cli add useOnScreen

Or copy and paste the code into your project:

ts
import { RefObject, useEffect, useState } from "react";

export default function useOnScreen(
  ref: RefObject<Element>,
  rootMargin = "0px"
): boolean {
  const [isIntersecting, setIntersecting] = useState(false);

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

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

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

  return isIntersecting;
}
js
import { useEffect, useState } from "react";

export default function useOnScreen(ref, rootMargin = "0px") {
  const [isIntersecting, setIntersecting] = useState(false);

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

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

    return () => {
      observer.unobserve(ref.current);
    };
  }, [ref, rootMargin]);

  return isIntersecting;
}

Requirements

React 16.8 or higher

Parameters

ref required

Type: RefObject<Element>

The DOM element you want to monitor.

rootMargin

Type: string

The margin around the root element to expand or shrink the visibility area.

Return values

isIntersecting

Type: boolean

Indicates whether the DOM element is currently visible on the screen (true) or not (false).

Example

tsx
import { useRef } from "react";
import useOnScreen from "./hooks/useOnScreen";

const App = () => {
  const ref = useRef(null);
  const isOnScreen = useOnScreen(ref);

  return (
    <div>
      <div style={{ height: "100vh" }}>Scroll down</div>
      <div
        ref={ref}
        style={{
          height: "100px",
          background: isOnScreen ? "green" : "red",
        }}
      >
        {isOnScreen ? "I am on screen!" : "I am off screen!"}
      </div>
      <div style={{ height: "100vh" }}>Scroll up</div>
    </div>
  );
};

export default App;

Use cases

Here are some use cases where this React hook is useful:

  • Trigger animations when an element becomes visible
  • Load images or content only when they are scrolled into view
  • Implement infinite scroll or pagination when a user reaches the end of the page