React Hooks
@macrulez/inview-react gives the same four capabilities as the Vue composables, built on useSyncExternalStore on top of the same framework-agnostic core engines — same API, same behavior, mirrored 1:1. Import everything from @macrulez/inview-react.
The differences from Vue are structural, not behavioral: plain values instead of Refs (no .value), a plain HTMLElement | null for target instead of MaybeRefOrGetter (React has no ref-as-reactive primitive to accept there — use a state-backed callback ref, not a plain useRef, if target needs to change after mount), and a static snapshot returned on the server via getServerSnapshot. For what each field actually means, see the linked core/Vue pages below — this page only calls out what's React-specific.
Reactive Scroll State
useScroll() — the React equivalent of Reactive Scroll State.
function useScroll(
target?: Window | HTMLElement | null,
options?: UseScrollOptions,
): UseScrollReturnSame fields (x, y, direction, progress, velocity, isScrolling, scrollTo), as plain values instead of refs. options.idleTimeout (default 150) works the same way.
Return value
| Field | Type |
|---|---|
x, y | number |
direction | 'up' | 'down' | 'left' | 'right' | null |
progress, velocity | number |
isScrolling | boolean |
scrollTo | (position: number | { x?: number; y?: number }, options?: ScrollToOptions) => void |
Example:
import { useScroll } from '@macrulez/inview-react'
function ScrollIndicator() {
const { y, isScrolling } = useScroll()
return isScrolling ? <p>{y}px</p> : null
}Element Visibility
useElementVisibility() — the React equivalent of Element Visibility.
function useElementVisibility(
target: HTMLElement | null,
options?: UseElementVisibilityOptions,
): UseElementVisibilityReturnUses the same shared, pooled visibility engine. options — threshold, rootMargin, once, onEnter, onLeave — same shape as Vue, except root: HTMLElement | null (a plain value, not MaybeRefOrGetter).
Real behavioral difference worth knowing: this hook does not read viewportDefaults/setViewportDefaults — those are Vue/Nuxt-only. threshold/rootMargin default to 0/'0px' here purely from the core ObserverPool's own fallback, so calling the Vue package's setViewportDefaults() has no effect on the React adapter.
Return value
| Field | Type |
|---|---|
isVisible | boolean |
ratio | number |
Element Viewport Position
useElementViewport() — the React equivalent of Element Viewport Position.
function useElementViewport(target: HTMLElement | null): UseElementViewportReturnReturns the same shape — rect, viewportProgress, distanceFromCenter — as plain values.
Parallax Layer
useParallaxLayer() — the React equivalent of Parallax Layer.
function useParallaxLayer(
target: HTMLElement | null,
options: UseParallaxLayerOptions,
): UseParallaxLayerReturnSame options (speed required, axis, clamp, easing, range), same mapping logic, same prefers-reduced-motion behavior. style/progress are memoized with useMemo rather than being a Vue computed.
Return value
| Field | Type |
|---|---|
style | { transform: string } |
progress | number |
Example:
import { useParallaxLayer } from '@macrulez/inview-react'
function ParallaxImage() {
const ref = useRef<HTMLImageElement | null>(null)
const { style } = useParallaxLayer(ref.current, { speed: 0.6 })
return <img ref={ref} style={style} src="/hero.jpg" />
}