Skip to content

Instantly share code, notes, and snippets.

@willmanduffy
Created July 22, 2019 16:25
Show Gist options
  • Select an option

  • Save willmanduffy/ebcb28577ac8fc192040c334c1555971 to your computer and use it in GitHub Desktop.

Select an option

Save willmanduffy/ebcb28577ac8fc192040c334c1555971 to your computer and use it in GitHub Desktop.
Infinite Scroll
import React, { useEffect, useState } from 'react';
import { useInView } from 'react-intersection-observer';
const WithInfiniteScrolling = ({
children,
hasMultiplePages,
loading,
loadMoreFunction,
requireButtonClick = true
}) => {
const [infiniteDisabled, setInfiniteDisabled] = useState(requireButtonClick);
const [beaconRef, beaconInView] = useInView();
const eligibleToLoadMore = hasMultiplePages && !infiniteDisabled && !loading;
useEffect(() => {
if (eligibleToLoadMore && beaconInView) {
loadMoreFunction();
}
}, [eligibleToLoadMore, beaconInView]);
return (
<>
{children}
<div className="collection-frame-footer">
{hasMultiplePages && infiniteDisabled && !loading && (
<button
id="test-infinite-scroll-load-more-button"
onClick={() => {
setInfiniteDisabled(false);
loadMoreFunction();
}}
>
That's not enough
</button>
)}
{loading && <span>Loading...</span>}
{/* When this beacon comes into view (via IntersectionObserver) we will trigger the
loadMoreFunction. The absolute positioning / negative margin is to help deal with
latency as it will come into view before the bottom of the loaded collection. */}
{eligibleToLoadMore && (
<div
id="test-infinite-scroll-beacon"
ref={beaconRef}
style={{ position: 'absolute', marginTop: '-500px' }}
/>
)}
</div>
</>
);
};
export default WithInfiniteScrolling;
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment