JAVASCRIPT
Detect if an Element is in Viewport with `useInView` Hook
Create a custom React hook `useInView` to efficiently determine if a given DOM element is currently within the user's viewport using `IntersectionObserver`, perfect for lazy loading and animations.
import React, { useRef, useState, useEffect } from 'react';
const useInView = (options) => {
const [isInView, setIsInView] = useState(false);
const elementRef = useRef(null);
useEffect(() => {
const observer = new IntersectionObserver(([entry]) => {
setIsInView(entry.isIntersecting);
}, options);
if (elementRef.current) {
observer.observe(elementRef.current);
}
return () => {
if (elementRef.current) {
observer.unobserve(elementRef.current);
}
};
}, [options]); // Re-run if options change (e.g., threshold)
return [elementRef, isInView];
};
// Example Usage:
// function MyComponent() {
// const [ref, inView] = useInView({ threshold: 0.5 });
//
// return (
// <div style={{ height: '100vh', background: 'lightgray' }}>
// Scroll down
// </div>
// <div ref={ref} style={{ height: '100vh', background: inView ? 'lightgreen' : 'salmon' }}>
// {inView ? 'I am in view!' : 'Scroll me into view!'}
// </div>
// <div style={{ height: '100vh', background: 'lightgray' }}>
// Scroll up
// </div>
// );
// }
How it works: This `useInView` hook leverages the browser's `IntersectionObserver` API to detect when a referenced DOM element enters or exits the viewport. It returns a `ref` to attach to the target element and a boolean `isInView` indicating its visibility. This is highly efficient for implementing features like lazy loading images, animating elements as they appear, or triggering analytics events without constantly checking scroll positions. The `options` parameter allows customization of the observer's behavior, such as `threshold` for partial visibility.