Hoist pagination to parent component
This commit is contained in:
parent
968194c38b
commit
85688d202a
@ -34,13 +34,14 @@ export default async function HomePage() {
|
||||
<MoreComponents
|
||||
label="More photos"
|
||||
itemsPerRequest={LARGE_PHOTOS_TO_SHOW}
|
||||
itemsTotalCount={count}
|
||||
componentLoader={async (limit: number) => {
|
||||
'use server';
|
||||
return <PhotosLarge
|
||||
photos={(await getPhotosCached({ limit }))
|
||||
.slice(LARGE_PHOTOS_TO_SHOW)}
|
||||
/>;
|
||||
return {
|
||||
component: <PhotosLarge
|
||||
photos={(await getPhotosCached({ limit }))
|
||||
.slice(LARGE_PHOTOS_TO_SHOW)} />,
|
||||
isFinished: limit > count,
|
||||
};
|
||||
}}
|
||||
/>
|
||||
</Suspense>
|
||||
|
||||
@ -6,14 +6,16 @@ import SiteGrid from './SiteGrid';
|
||||
|
||||
export default function MoreComponents({
|
||||
itemsPerRequest,
|
||||
itemsTotalCount,
|
||||
componentLoader,
|
||||
label = 'Load more',
|
||||
triggerOnView = true,
|
||||
prefetch = true,
|
||||
}: {
|
||||
itemsPerRequest: number
|
||||
itemsTotalCount: number
|
||||
componentLoader: (limit: number) => Promise<JSX.Element>
|
||||
componentLoader: (start: number, offset: number) => Promise<{
|
||||
component: JSX.Element,
|
||||
isFinished: boolean,
|
||||
}>
|
||||
label?: string
|
||||
triggerOnView?: boolean
|
||||
prefetch?: boolean
|
||||
@ -21,22 +23,31 @@ export default function MoreComponents({
|
||||
const [offset, setOffset] = useState(2);
|
||||
const [components, setComponents] = useState<JSX.Element[]>([]);
|
||||
const [isLoading, setIsLoading] = useState(false);
|
||||
const [isFinished, setIsFinished] = useState(false);
|
||||
|
||||
const buttonRef = useRef<HTMLButtonElement>(null);
|
||||
|
||||
const advance = useCallback(() => {
|
||||
setIsLoading(true);
|
||||
const getMoreComponentsAsync = async () => {
|
||||
return componentLoader(itemsPerRequest * offset);
|
||||
return componentLoader(0, itemsPerRequest * offset);
|
||||
};
|
||||
getMoreComponentsAsync()
|
||||
.then(component => {
|
||||
.then(({ component, isFinished }) => {
|
||||
setComponents([component]);
|
||||
setIsFinished(isFinished);
|
||||
setOffset(o => o + 1);
|
||||
})
|
||||
.finally(() => setIsLoading(false));
|
||||
}, [componentLoader, itemsPerRequest, offset]);
|
||||
|
||||
// useEffect(() => {
|
||||
// if (prefetch && components.length < offset) {
|
||||
// console.log('prefetching');
|
||||
// advance();
|
||||
// }
|
||||
// }, [prefetch, advance, components.length, offset]);
|
||||
|
||||
useEffect(() => {
|
||||
// Only add observer if button is rendered
|
||||
if (buttonRef.current) {
|
||||
@ -59,11 +70,9 @@ export default function MoreComponents({
|
||||
}
|
||||
}, [triggerOnView, advance, isLoading]);
|
||||
|
||||
const showMoreButton = itemsTotalCount > itemsPerRequest * (offset - 1);
|
||||
|
||||
return <>
|
||||
{components}
|
||||
{showMoreButton &&
|
||||
{!isFinished &&
|
||||
<SiteGrid
|
||||
contentMain={
|
||||
<button
|
||||
|
||||
@ -11,7 +11,7 @@ import {
|
||||
import camelcaseKeys from 'camelcase-keys';
|
||||
import type { Metadata } from 'next';
|
||||
|
||||
export const LARGE_PHOTOS_TO_SHOW = 12;
|
||||
export const LARGE_PHOTOS_TO_SHOW = 3;
|
||||
export const GRID_THUMBNAILS_TO_SHOW_MAX = 12;
|
||||
|
||||
export const ACCEPTED_PHOTO_FILE_TYPES = [
|
||||
|
||||
Loading…
Reference in New Issue
Block a user