Skip to content

Instantly share code, notes, and snippets.

@LironHazan
Created March 26, 2022 14:59
Show Gist options
  • Save LironHazan/9efbc3d3fd205eeaba794e1654c15747 to your computer and use it in GitHub Desktop.
Save LironHazan/9efbc3d3fd205eeaba794e1654c15747 to your computer and use it in GitHub Desktop.
A react utility component for Lazy-loading of content as a page is scrolled
import React, { useState, useRef, useEffect } from 'react';
import RectContentLoader from './RectContentLoader';
export interface VirtRenderingProps {
placeholderHeight?: number; // the height of the rendered item
root?: HTMLElement | null; // If the root is null, then the bounds of the actual document viewport are used.
children: React.ReactNode;
}
/**
* A utility component for Lazy-loading of content as a page is scrolled.
* @param placeholderHeight
* @param root
* @param children
* @constructor
*/
const LazyLoadChildren = ({
placeholderHeight = 40,
root = null,
children,
}: VirtRenderingProps) => {
const [isVisible, setIsVisible] = useState<boolean>(false);
const intersectionRef = useRef<HTMLDivElement>(null);
const _placeholderHeight =
intersectionRef?.current?.offsetHeight ?? placeholderHeight;
useEffect(() => {
let observer: IntersectionObserver;
const currentIntersectionRef = intersectionRef.current;
if (currentIntersectionRef) {
observer = new IntersectionObserver(
(entries) => {
if (window?.requestIdleCallback) {
window.requestIdleCallback(
() => setIsVisible(entries[0].isIntersecting),
{
timeout: 500,
}
);
} else {
setIsVisible(entries[0].isIntersecting);
}
},
{ root }
);
observer.observe(currentIntersectionRef);
return () =>
currentIntersectionRef && observer.unobserve(currentIntersectionRef);
}
return () =>
currentIntersectionRef && observer.unobserve(currentIntersectionRef);
}, [intersectionRef]);
return (
<div ref={intersectionRef}>
{isVisible ? (
<>{children}</>
) : (
<RectContentLoader
placeholderHeight={_placeholderHeight || placeholderHeight}
/>
)}
</div>
);
};
export default LazyLoadChildren;
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment