Baike.dev
All toolsAI codingTrendingOpen sourceNewsSubmit
Log in
< Back to tools
R

react-cool-inview

> 前端框架
Open source

️ React hook to monitor an element enters or leaves the viewport (or another element).

1.5K stars0 likes0 views
WebsiteGitHub

About

️ React hook to monitor an element enters or leaves the viewport (or another element).

REACT COOL INVIEW

A React hook / component API that monitors an element enters or leaves the viewport (or another element) with highly-performant way, using Intersection Observer. It's lightweight and super flexible, which can cover all the cases that you need, like lazy-loading images and videos, infinite scroll web app, triggering animations, tracking impressions, and more. Try it you will it!

❤️ it? ⭐️ it on GitHub or Tweet about it.

⚡️ Try yourself: https://react-cool-inview.netlify.app

Features

  • Monitors elements with highly-performant and non-main-thread blocking way, using Intersection Observer.
  • Easy to use, based on React hook / component.
  • Super flexible API design which can cover all the cases that you need.
  • ️ Supports scroll direction, cool right?
  • ✌ Supports Intersection Observer v2.
  • Supports TypeScript type definition.
  • ️ Server-side rendering compatibility.
  • Tiny size (~ 1.2kB gzipped). No external dependencies, aside for the react.

Requirement

To use react-cool-inview, you must use [email protected] or greater which includes hooks.

Installation

This package is distributed via npm.

$ yarn add react-cool-inview
# or
$ npm install --save react-cool-inview

Usage

react-cool-inview has a flexible API design, it can cover simple to complex use cases for you. Here are some ideas for how you can use it.

⚠️ Most modern browsers support Intersection Observer natively. You can also add polyfill for full browser support.

Basic usage

To monitor an element enters or leaves the viewport by the inView state and useful sugar events.

…

You don't have to call unobserve when the component is unmounted, this hook will handle it for you.

Using as a Component

Changes HelloText when it enters the viewport. The options can be passed through the props.

import { InView } from "react-cool-inview";

const HelloText = ({ inView, observe }) => (
  

);

const App = () => (
  <InView unobserveOnEnter>
    <HelloText />
  </InView>
);

InView passes observe and other props to the HelloText.

Lazy-loading Images

It's super easy to build an image lazy-loading component with react-cool-inview to boost the performance of your web app.

import { useInView } from "react-cool-inview";

const LazyImage = ({ width, height, ...rest }) => {
  const { observe, inView } = useInView({
    // Stop observe when the target enters the viewport, so the "inView" only triggered once
    unobserveOnEnter: true,
    // For better UX, we can grow the root margin so the image will be loaded before it comes to the viewport
    rootMargin: "50px",
  });

  return (
    

  );
};

Looking for a comprehensive image component? Try react-cool-img, it's my other component library.

Infinite Scroll

Infinite scroll is a popular design technique like Facebook and Twitter feed etc., new content being loaded as you scroll down a page. The basic concept as below.

…

Compare to pagination, infinite scroll provides a seamless experience for users and it’s easy to see the appeal. But when it comes to render a large lists, performance will be a problem. But don't worry, react-cool-virtual can help you out!

Trigger Animations

Another great use case is to trigger CSS animations once they are visible to the users.

import { useInView } from "react-cool-inview";

const App = () => {
  const { observe, inView } = useInView({
    // Stop observe when the target enters the viewport, so the "inView" only triggered once
    unobserveOnEnter: true,
    // Shrink the root margin, so the animation will be triggered once the target reach a fixed amount of visible
    rootMargin: "-100px 0px",
  });

  return (
    

    </div>
  );
};

Track Impressions

react-cool-inview can also play as an impression tracker, helps you fire an analytic event when a user sees an element or advertisement.

import { useInView } from "react-cool-inview";

const App = () => {
  const { observe } = useInView({
    // For an element to be considered "seen", we'll say it must be 100% in the viewport
    threshold: 1,
    onEnter: ({ unobserve }) => {
      // Stop observe when the target enters the viewport, so the callback only triggered once
      unobserve();
      // Fire an analytic event to your tracking service
      someTrackingService.send(" is seen");
    },
  });

  return 
;
};

Scrolling Direction

react-cool-inview not only monitors an element enters or leaves the viewport but also tells you its scroll direction by the scrollDirection object. The object contains vertical (y-axios) and horizontal (x-axios) properties, they're calculated whenever the target element meets a threshold. If there's no enough condition for calculating, the value of the properties will be undefined. In addition, the value of the properties will sync with the scrolling direction of the viewport.

…

If you jump to a section by the Element.scrollTop and encounter the wrong value of the scrollDirection. You can use updatePosition method to correct the behavior.

import { useEffect } from "react";
import { useInView } from "react-cool-inview";

const App = () => {
  const { observe, scrollDirection, updatePosition } = useInView({
    threshold: [0.2, 0.4, 0.6, 0.8, 1],
  });

  useEffect(() => {
    window.scrollTo(0, 500);
    updatePosition(); // Ensure the target element's position has been updated after the "window.scrollTo"
  }, []);

  return (
    

    </div>
  );
};

Intersection Observer v2

The Intersection Observer v1 can perfectly tell you when an element is scrolled into the viewport, but it doesn't tell you whether the element is covered by something else on the page or whether the element has any visual effects applied to it (like transform, opacity, filter etc.) that can make it invisible. The main concern that has surfaced is how this kind of knowledge could be helpful in preventing clickjacking and UI redress attacks (read this article to learn more).

If you want to track the click-through rate (CTR) or impression of an element, which is actually visible to a user, Intersection Observer v2 can be the savior. Which introduces a new boolean field named isVisible. A true value guarantees that an element is visible on the page and has no visual effects applied on it. A false value is just the opposite. The characteristic of the isVisible is integrated with the inView state and related events (like onEnter, onLeave etc.) to provide a better DX for you.

When using the v2, there're somethings we need to know:

  • Check browser compatibility. If a browser doesn't support the v2, we will fallback to the v1 behavior.
  • Understand how visibility is calculated.
  • Visibility is much more expensive to compute than intersection, only use it when needed.

To use Intersection Observer v2, we must set the trackVisibility and delay options.

…

How to Share A ref?

You can share a ref as follows:

import { useRef } from "react";
import { useInView } from "react-cool-inview";

const App = () => {
  const ref = useRef();
  const { observe } = useInView();

  return (
    <div
      ref={(el) => {
        observe(el); // Set the target element for monitoring
        ref.current = el; // Share the element for other purposes
      }}
    />
  );
};

Working in TypeScript

This hook supports TypeScript, you can tell the hook what type of element you are going to observe through the generic type:

const App = () => {
  const { observe } = useInView<HTMLDivElement>();

  return <div ref={observe} />;
};

For more available types, please check it out.

API

const returnObj = useInView(options?: object);

Return object

It's returned with the following properties.

Key Type Default Description
observe function To set a target element for monitoring or re-start observing the current target element.
unobserve function To stop observing the current target element.
inView boolean The visible state of the target element. If it's true, the target element has become at least as visible as the threshold that was passed. If it's false, the target element is no longer as visible as the given threshold. Supports Intersection Observer v2.
scrollDirection object The scroll direction of the target element. Which contains vertical and horizontal properties. See scroll direction for more information.

Issues· 19 open

View all issuesOpen on GitHub

No open issues yet, or sync has not completed.

> Tags

TypeScriptanimationscomponenthookimpressions

No comments yet. Be the first to share.

> Details

PublishedAug 1, 2026
UpdatedSep 17, 2026
Category前端框架
PricingOpen source

> Related tools

R
React
用于构建用户界面的 JavaScript 库
V
Vue.js
渐进式 JavaScript 框架
N
Next.js
基于 React 的全栈 Web 框架