# useInView

Whether an element is visible in the viewport, using IntersectionObserver.

Returns a callback ref to put on the element. It is `false` on the server, during hydration, and until the observer first reports. Does not re-render on scroll, only when visibility changes.

## Import

```ts
import { useInView } from '@vincent.ri/react-tils'
// or only this hook
import { useInView } from '@vincent.ri/react-tils/useInView'
```

## Usage

```ts
// Load more when the sentinel gets within 300px of the viewport.
const [ref, inView] = useInView<HTMLDivElement>({ rootMargin: '300px' })
useEffect(() => {
  if (inView) loadMore()
}, [inView])
return <div ref={ref} />
```

## When to use it

Lazy-loading content or images, loading the next page of an infinite list, starting an animation or video when it scrolls into view, or tracking impressions.

## When not to

You need the exact scroll position; use `useWindowScroll`. For images alone, `<img loading="lazy">` needs no JS.

## API

```ts
function useInView<T extends Element = HTMLElement>(options?: InViewOptions): [(element: T | null) => void, boolean]
```

| Parameter | Description |
| --- | --- |
| `options` | `rootMargin`, `threshold`, and `once`. All optional. |

**Returns** `[ref, inView]`. Pass `ref` to the element's `ref` prop.

### Types

```ts
export type InViewOptions = {
  /** Grow or shrink the viewport for the check, like CSS margin. E.g. `'200px'` triggers 200px early. */
  rootMargin?: string;
  /** Fraction of the element (0 to 1) that must be visible. Default `0`: any pixel. */
  threshold?: number;
  /** Stop observing after the first time the element is in view. Default `false`. */
  once?: boolean;
};
```

## Browser support

Works in all modern browsers.

## Coming from another library?

Other libraries call this `useIntersection`, `useIntersectionObserver`, `useInViewport`.

---

252 B minified and brotlied
Source: https://github.com/vincentri/react-tils/blob/main/src/useInView.ts
Docs page: https://vincentri.github.io/react-tils/hooks/useInView/
Previous: [useElementScroll](https://vincentri.github.io/react-tils/hooks/useElementScroll.md)
Next: [useIsStuck](https://vincentri.github.io/react-tils/hooks/useIsStuck.md)
