useOnScreen.js
Overview
useOnScreen.js defines a custom React Hook named useOnScreen that detects whether a referenced DOM element is currently visible within the viewport. It leverages the browser's native IntersectionObserver API to efficiently observe the visibility state of an element without polling or expensive event listeners.
This hook is primarily used to trigger UI changes or lazy-load content when an element scrolls into or out of view, improving performance and user experience in React applications.
Detailed Explanation
useOnScreen(ref)
Description
A React Hook that returns a boolean indicating whether the DOM element referenced by ref is visible on the user's screen.
Parameters
ref(React.RefObject<HTMLElement>): A React ref object pointing to a DOM element to observe. The element must be mounted in the DOM for observation to occur.
Returns
boolean:trueif the referenced element is currently intersecting (visible) in the viewport; otherwise,false.
Usage Example
import React, { useRef } from 'react';
import useOnScreen from './useOnScreen';
function LazyImage() {
const imgRef = useRef();
const isVisible = useOnScreen(imgRef);
return (
<img
ref={imgRef}
src={isVisible ? 'high-res-image.jpg' : 'placeholder.jpg'}
alt="Lazy loaded example"
style={{ width: '100%', height: 'auto' }}
/>
);
}
In this example, the image source switches to a high-resolution image only when the image enters the viewport.
Implementation Details
State Management:
The hook internally uses React'suseStateto keep track of the intersection status (isIntersecting).Effect Hook:
TheuseEffecthook initializes anIntersectionObserverwhen the component mounts and attaches it to the DOM element referenced byref.IntersectionObserver API:
This browser API asynchronously observes changes in the intersection of a target element with an ancestor element or with a top-level document’s viewport. The hook sets the state totrueorfalsebased on the observation.Cleanup:
The observer is disconnected on component unmount to avoid memory leaks and unnecessary observations.Empty Dependency Array:
TheuseEffecthas an empty dependency array[], meaning the observer is created once on mount and cleaned up on unmount. The assumption here is that therefdoes not change during the component lifecycle.
Interaction with Other Parts of the System
UI Components:
This hook is designed to be used inside React functional components that need to react to visibility changes of their elements on screen.Performance Optimization:
By usinguseOnScreen, components can implement lazy loading for images, animations, or data fetching only when the element is visible, thus improving performance and reducing bandwidth.No External Dependencies:
The hook uses only React and browser APIs, so it integrates seamlessly into any React codebase without additional dependencies.
Mermaid Diagram
flowchart TD
A[Component with ref] --> B[useOnScreen(ref)]
B --> C[useState(isIntersecting)]
B --> D[useEffect()]
D --> E[IntersectionObserver]
E --> F[observe ref.current]
E --> G[callback: setIntersecting(entry.isIntersecting)]
D --> H[cleanup: observer.disconnect()]
B --> I[return isIntersecting]
Diagram Explanation:
A React component provides a
reftouseOnScreen.useOnScreeninitializes state and effect hooks.The effect creates an
IntersectionObserverthat observes the DOM element referenced byref.When the element's visibility changes, the observer callback updates the state.
The hook returns the current visibility state to the component.
Cleanup disconnects the observer on unmount.
Summary
useOnScreen.js is a lightweight, reusable React Hook that abstracts the complexity of the IntersectionObserver API to provide a simple boolean flag indicating element visibility on screen. It is useful in performance-sensitive React applications for implementing lazy loading and viewport-aware behaviors. The hook cleanly manages lifecycle and state with React hooks and requires only a single ref parameter to function.
End of Documentation