react-intersection-observer is a comprehensive React library that provides hooks and components for efficiently leveraging the browser's Intersection Observer API. It allows developers to monitor when a React component enters or leaves the viewport, enabling features like lazy loading images, implementing infinite scrolling, or triggering animations based on visibility. The current stable version is `10.0.3`, and the project maintains an active release cadence, frequently pushing updates and bug fixes. Key differentiators include its dual API (hooks like `useInView` and `useOnInView`, plus a `<InView>` component), optimized performance through observer instance reuse, native API alignment, robust TypeScript support, and a tiny bundle size (around ~1.15kB for `useInView`). The `useOnInView` hook, introduced in v10, offers a no-re-render alternative for side-effect-heavy workloads like analytics tracking, further enhancing its utility. It also includes comprehensive test utilities for Jest and Vitest.
npm install react-intersection-observerVerified import paths — ran on the pinned version, not inferred.
This example demonstrates how to use the `useInView` hook to lazy load an image. The image only renders once it enters the viewport, using `triggerOnce` and a `threshold` of 0.1.
Upgrade your project's React and React-DOM dependencies to version 17.0.0 or higher. Alternatively, pin `react-intersection-observer` to a version below 9.14.0, such as `"react-intersection-observer": "^9.13.0"`.
Wrap your `options` object in `React.useMemo` or define it outside the component, especially if it contains complex logic or changes on every render:
```typescript
const options = React.useMemo(() => ({ threshold: 0.5, triggerOnce: true }), []);
const { ref, inView } = useInView(options);
```Ensure you are on `react-intersection-observer@10.0.3` or newer to benefit from the fix regarding `triggerOnce` and merged refs. If upgrading is not immediately possible, consider alternative logic for `triggerOnce` or simplify ref merging.
Be aware of this initial behavior. If you need to explicitly handle the initial 'out of view' state, you might need to use a `useEffect` hook with a default `inView` state or an explicit check outside the `useInView` callback.
Ensure you are using ESM `import` statements: `import { useInView } from 'react-intersection-observer';`. If using TypeScript with CommonJS output, verify your `tsconfig.json` `module` option (e.g., `"ESNext"` or `"Node16"`) and your bundler's settings (e.g., Webpack, Rollup, Vite) support ESM correctly.Move the `useInView` call directly into the body of your React functional component or into another custom hook. Hooks must always be called at the top level of a component or custom hook.
Double-check your `threshold` (e.g., `threshold: 0` means any part visible, `threshold: 1` means entirely visible) and `rootMargin` (e.g., `rootMargin: '10px 0px'` extends the root bounds). Ensure the `ref` returned by `useInView` is correctly assigned to the DOM element you intend to observe: `<div ref={ref}>...</div>`.