useIntersectionObserver
useIntersectionObserver is the lower-level visibility hook in react-rsc-kit.
It supports both an external ref and the callback ref returned by the hook.
Live Example
Scrollable visibility tracker
This demo uses the real hook against a scroll container so you can see the observer state update live.
Scroll inside the demo area. The observed card updates when it enters the tracked viewport.
Scroll down
Outside the viewportIntersection ratio: 0.00Seen at least once: false
Import
import { useIntersectionObserver } from "react-rsc-kit/client";Signature
const result = useIntersectionObserver<T>(options?);Parameters
| Name | Type | Default | Description |
|---|---|---|---|
ref | React.RefObject<T | null> | null | undefined | Optional external ref for the target element. |
root | Element | Document | React.RefObject<Element | null> | null | null | Custom observer root. |
rootMargin | string | "0px" | Root margin passed to the observer. |
threshold | number | number[] | 0 | Visibility threshold or thresholds. |
freezeOnceVisible | boolean | false | Stops observing after the first visible intersection. |
triggerOnce | boolean | false | Legacy compatibility alias for freezeOnceVisible. |
disabled | boolean | false | Prevents observation without unmounting the hook. |
initialIsIntersecting | boolean | false | Initial visibility state before the first observer update. |
fallbackInView | boolean | undefined | Fallback visibility state when IntersectionObserver is unavailable. |
onChange | (entry, observer) => void | undefined | Runs on each observer update. |
Returns
| Key | Description |
|---|---|
ref | Callback ref for the target element. |
entry | Latest IntersectionObserverEntry or null. |
isIntersecting | Whether the target is currently visible. |
hasIntersected | Whether the target has ever intersected in the current lifecycle. |
intersectionRatio | Latest ratio, defaults to 0. |
boundingClientRect | Latest bounding rect or null. |
intersectionRect | Latest intersection rect or null. |
rootBounds | Latest root bounds or null. |
time | Timestamp from the latest entry. |
target | Current observed node or null. |
isSupported | Whether IntersectionObserver exists in the current environment. |
disconnect | Manually disconnects the active observer. |
Usage
"use client";
import { useIntersectionObserver } from "react-rsc-kit/client";
export function LazyImage({ src }: { src: string }) {
const { ref, isIntersecting } = useIntersectionObserver<HTMLDivElement>({
threshold: 0.25,
freezeOnceVisible: true,
});
return <div ref={ref}>{isIntersecting ? <img src={src} alt="" /> : null}</div>;
}Notes
freezeOnceVisibleis the preferred option name.- Use
refwhen the target node is created inside the same component. - For a simpler boolean-only API, use
useOnScreen.
Last updated on