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