Infinite Scroll
Do you have a list of data that users scroll through? Maybe it's a list of payments, or transactions or bills. Probably something where you've scrolling further back in time. Well, we have a component that integrates with react-query's infinite query to load in more elements from the list as the user scrolls down the page.
Check out this example:
In InfiniteBillsList.tsx
, we import the utility InfiniteScroll
. We pass this component the props from the
useInfiniteQuery
hook (fetchNextPage
, hasNextPage
, data
... etc), as well a the RenderComponent={BillsList}
,
which is given below.
import { InfiniteScroll } from '@krakentech/blueprint-utils';
// standard list component that takes data and displays list with items
import BillsList from './BillsList';
// example custom utility that we want to pass to our BillsList component
import { createDownloadUrl } from './utils';
const InfiniteBillsList = ({
fetchNextPage,
hasNextPage,
data,
error,
isFetching,
}) => {
return (
<InfiniteScroll
loadMoreText={'Load more'}
loadFn={fetchNextPage}
hasNextPage={hasNextPage}
data={data}
error={error}
isFetching={isFetching}
downloadBillUrlFunc={({ billId }: { billId: string }) =>
createDownloadUrl(billId)
}
RenderComponent={BillsList}
/>
);
};
In BillsList.tsx
we define the standard React component we want to render the items in the list. This is the component
that was passed to the RenderComponent
prop of InfiniteScoll
. The RenderComponent
is passed the data
and error
props, along with any custom props we defined like downloadBillUrlFunc
.
import { useMemo } from 'react';
import { Loader, Typography, Error, Stack, Container } from '@krakentech/coral';
import { BillListItem } from './Bills';
const BillsList = ({ data, error, downloadBillUrlFunc }) => {
const statements = useMemo(() => data?.pages?.flat(1), [data]);
if (statements) {
return (
<Container marginBottom="lg">
<Stack gap="sm" direction="vertical">
{statements?.length ? (
statements.map((statement) => (
<BillListItem
key={statement.id}
page={statement}
downloadBillUrl={downloadBillUrlFunc({
billId: statement.id,
})}
testId={`bill-${statement.id}`}
/>
))
) : (
<Typography variant="h3">
No bills to display
</Typography>
)}
</Stack>
</Container>
);
}
if (error) {
return <Error />;
}
return <Loader />;
};
And here is an example of this component in action. If you scroll to the bottom, a 'Load more' button is briefly visible. This button is provided to allow for keyboard accessibility. If you open the developer tools for the page, you'll also see the mocked request trigger in the network tab.