Skip to content

Instantly share code, notes, and snippets.

@iamalvisng
Last active August 7, 2023 03:40
Show Gist options
  • Save iamalvisng/41d46c79d4d8ce464df9eb19f8aed065 to your computer and use it in GitHub Desktop.
Save iamalvisng/41d46c79d4d8ce464df9eb19f8aed065 to your computer and use it in GitHub Desktop.
Infinite scroll using Intersection Observer API
import React, { useEffect, useRef } from 'react';
// Define the properties for the InfiniteScrollTrigger component
type InfiniteScrollTriggerProps = {
onIntersect: () => void; // Callback function to be executed when intersection is detected
root?: Element | Document | null; // The Element or Document object to be used as the viewable area for the IntersectionObserver
threshold?: number; // A single number or an array of numbers between 0.0 and 1.0 indicating at what percentage of the target's visibility the observer's callback should be executed
rootMargin?: string; // Margin around the root. Can have values similar to the CSS margin property
};
export function InfiniteScrollTrigger({
onIntersect, // function to execute when intersection happens
root, // root element for the intersection observer
threshold = 1.0, // Intersection ratio to trigger the intersection observer. Defaults to 1 (100% visibility)
rootMargin = '0px', // margin around the root, defaults to '0px'
}: InfiniteScrollTriggerProps) {
const targetRef = useRef<HTMLDivElement | null>(null); // A ref that points to the element that will be observed for intersection
const observerRef = useRef<IntersectionObserver | null>(null); // A ref that stores the IntersectionObserver instance
useEffect(() => {
const target = targetRef.current; // Get the current target
// Create and store the intersection observer
observerRef.current = new IntersectionObserver(
([entry]: IntersectionObserverEntry[]) => { // Array destructuring is used to get the first entry from the entries array
if (entry.isIntersecting) { // Check if the target is intersecting
onIntersect(); // If it is, call the onIntersect function
}
},
{ root, rootMargin, threshold } // Options object for the intersection observer
);
// If the target exists and the observer has been created, start observing the target
if (target && observerRef.current) {
observerRef.current.observe(target);
}
// Cleanup function to stop observing the target when the component unmounts or any of the dependencies change
return () => {
if (target && observerRef.current) {
observerRef.current.unobserve(target);
}
};
}, [onIntersect, root, rootMargin, threshold]); // Dependencies array for the useEffect hook
// Return a div that will be observed for intersection
return <div ref={targetRef} />;
}
import React from 'react';
import { InfiniteScrollTrigger } from './InfiniteScrollTrigger';
export default function MyComponent() {
// This function will be called each time the trigger is intersected
const loadMoreData = () => {
console.log("Intersection detected. Load more data!");
// Fetch more data here...
};
return (
<div>
{/* Some other components */}
<InfiniteScrollTrigger onIntersect={loadMoreData} />
</div>
);
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment