Last active
August 7, 2023 03:40
-
-
Save iamalvisng/41d46c79d4d8ce464df9eb19f8aed065 to your computer and use it in GitHub Desktop.
Infinite scroll using Intersection Observer API
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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} />; | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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