34 lines
1.2 KiB
TypeScript
34 lines
1.2 KiB
TypeScript
import * as React from "react";
|
|
import { useEffect, useCallback } from "react";
|
|
|
|
// From the Smashing Magazine article,
|
|
// https://www.smashingmagazine.com/2020/03/infinite-scroll-lazy-image-loading-react/
|
|
|
|
// As this is new to me, I'm going to try to explain it;
|
|
// IntersectionObserver takes a callback to be called when it's
|
|
// triggred. It's trigged when the node it's been asked to observe
|
|
// changes its relationship with another object or, without a
|
|
// specified object, with the viewport. When the `intersectionRatio`
|
|
// exceed zero, it is _intersecting_ the viewport, i.e. it is now
|
|
// visible.
|
|
|
|
// useCallback is a memoizer; it only updates the contents of the
|
|
// function its wrapped if the included function changes, which
|
|
// it shouldn't.
|
|
|
|
export const useInfiniteScroll = (scrollRef: React.RefObject<HTMLElement>, stateUpdate: Function) => {
|
|
const scrollObserver = (node: HTMLElement) => {
|
|
new IntersectionObserver(entries => {
|
|
if (entries.some(en => en.intersectionRatio > 0)) {
|
|
stateUpdate();
|
|
}
|
|
}).observe(node);
|
|
};
|
|
|
|
useEffect(() => {
|
|
if (scrollRef.current) {
|
|
scrollObserver(scrollRef.current);
|
|
}
|
|
}, [scrollObserver, scrollRef]);
|
|
}
|