Add ref controls to infinite grid

This commit is contained in:
jeffvli 2022-12-24 20:19:56 -08:00
parent 520b7ce136
commit 26ea4c0cc9

View file

@ -1,4 +1,12 @@
import { useState, useEffect, useRef, useMemo, useCallback } from 'react';
import {
useState,
useRef,
useMemo,
useCallback,
forwardRef,
Ref,
useImperativeHandle,
} from 'react';
import debounce from 'lodash/debounce';
import type { FixedSizeListProps } from 'react-window';
import InfiniteLoader from 'react-window-infinite-loader';
@ -6,6 +14,12 @@ import { VirtualGridWrapper } from '/@/renderer/components/virtual-grid/virtual-
import type { CardRoute, CardRow, LibraryItem, PlayQueueAddOptions } from '/@/renderer/types';
import { CardDisplayType } from '/@/renderer/types';
export type VirtualInfiniteGridRef = {
resetLoadMoreItemsCache: () => void;
scrollTo: (index: number) => void;
setItemData: (data: any[]) => void;
};
interface VirtualGridProps extends Omit<FixedSizeListProps, 'children' | 'itemSize'> {
cardRows: CardRow<any>[];
display?: CardDisplayType;
@ -15,7 +29,6 @@ interface VirtualGridProps extends Omit<FixedSizeListProps, 'children' | 'itemSi
itemSize: number;
itemType: LibraryItem;
minimumBatchSize?: number;
refresh?: any;
route?: CardRoute;
}
@ -27,7 +40,9 @@ const constrainWidth = (width: number) => {
return 1920;
};
export const VirtualInfiniteGrid = ({
export const VirtualInfiniteGrid = forwardRef(
(
{
itemCount,
itemGap,
itemSize,
@ -42,8 +57,9 @@ export const VirtualInfiniteGrid = ({
initialScrollOffset,
height,
width,
refresh,
}: VirtualGridProps) => {
}: VirtualGridProps,
ref: Ref<VirtualInfiniteGridRef>,
) => {
const [itemData, setItemData] = useState<any[]>([]);
const listRef = useRef<any>(null);
const loader = useRef<InfiniteLoader>(null);
@ -100,16 +116,20 @@ export const VirtualInfiniteGrid = ({
const debouncedLoadMoreItems = debounce(loadMoreItems, 500);
useEffect(() => {
useImperativeHandle(ref, () => ({
resetLoadMoreItemsCache: () => {
if (loader.current) {
listRef.current.scrollTo(0);
loader.current.resetloadMoreItemsCache(false);
setItemData(() => []);
loadMoreItems(0, minimumBatchSize! * 2);
}
// eslint-disable-next-line react-hooks/exhaustive-deps
}, [minimumBatchSize, fetchFn, refresh]);
},
scrollTo: (index: number) => {
listRef.current.scrollToItem(index);
},
setItemData: (data: any[]) => {
setItemData(data);
},
}));
return (
<InfiniteLoader
@ -147,11 +167,11 @@ export const VirtualInfiniteGrid = ({
)}
</InfiniteLoader>
);
};
},
);
VirtualInfiniteGrid.defaultProps = {
display: CardDisplayType.CARD,
minimumBatchSize: 20,
refresh: undefined,
route: undefined,
};