optimize render of listitem

This commit is contained in:
PhilReact 2025-06-30 10:43:43 +03:00
parent 5bd68768f9
commit 0933cb33ae
4 changed files with 43 additions and 18 deletions

View File

@ -1,6 +1,6 @@
{ {
"name": "qapp-core", "name": "qapp-core",
"version": "1.0.36", "version": "1.0.37",
"description": "Qortal's core React library with global state, UI components, and utilities", "description": "Qortal's core React library with global state, UI components, and utilities",
"main": "dist/index.js", "main": "dist/index.js",
"module": "dist/index.mjs", "module": "dist/index.mjs",

View File

@ -18,7 +18,7 @@ interface HorizontalPaginatedListProps {
defaultLoaderParams?: DefaultLoaderParams; defaultLoaderParams?: DefaultLoaderParams;
} }
export const HorizontalPaginatedList = ({ const MemorizedComponent = ({
items, items,
listItem, listItem,
loaderItem, loaderItem,
@ -30,6 +30,7 @@ export const HorizontalPaginatedList = ({
disablePagination, disablePagination,
defaultLoaderParams defaultLoaderParams
}: HorizontalPaginatedListProps) => { }: HorizontalPaginatedListProps) => {
const lastItemRef= useRef<any>(null) const lastItemRef= useRef<any>(null)
const lastItemRef2= useRef<any>(null) const lastItemRef2= useRef<any>(null)
const [columnsPerRow, setColumnsPerRow] = useState<null | number>(null) const [columnsPerRow, setColumnsPerRow] = useState<null | number>(null)
@ -102,3 +103,7 @@ const displayedItems = disablePagination ? items : items?.length < (displayedLim
</div> </div>
); );
}; };
export const HorizontalPaginatedList = React.memo(MemorizedComponent);

View File

@ -366,6 +366,13 @@ const setResourceCacheExpiryDuration = useCacheStore((s) => s.setResourceCacheEx
return listItem(item, index); return listItem(item, index);
}, [ listItem]); }, [ listItem]);
const onLoadLess = useCallback((displayLimit: number)=> {
removeFromList(listName, displayLimit)
}, [removeFromList])
const onLoadMore = useCallback((displayLimit: number)=> {
getResourceMoreList(displayLimit)
}, [getResourceMoreList])
return ( return (
<div ref={elementRef} style={{ <div ref={elementRef} style={{
width: '100%', width: '100%',
@ -417,9 +424,7 @@ const setResourceCacheExpiryDuration = useCacheStore((s) => s.setResourceCacheEx
)} )}
{disableVirtualization && direction === "HORIZONTAL" && ( {disableVirtualization && direction === "HORIZONTAL" && (
<> <>
<HorizontalPaginatedList defaultLoaderParams={defaultLoaderParams} disablePagination={disablePagination} limit={search?.limit || 20} onLoadLess={(displayLimit)=> { <HorizontalPaginatedList defaultLoaderParams={defaultLoaderParams} disablePagination={disablePagination} limit={search?.limit || 20} onLoadLess={onLoadLess} items={listToDisplay} listItem={renderListItem} onLoadMore={onLoadMore} gap={styles?.gap} minItemWidth={styles?.horizontalStyles?.minItemWidth} loaderItem={loaderItem} />
removeFromList(listName, displayLimit)
}} items={listToDisplay} listItem={renderListItem} onLoadMore={(displayLimit)=> getResourceMoreList(displayLimit)} gap={styles?.gap} minItemWidth={styles?.horizontalStyles?.minItemWidth} loaderItem={loaderItem} />
</> </>
)} )}
@ -458,7 +463,6 @@ function arePropsEqual(
export const ResourceListDisplay = React.memo(MemorizedComponent, arePropsEqual); export const ResourceListDisplay = React.memo(MemorizedComponent, arePropsEqual);
interface ListItemWrapperProps { interface ListItemWrapperProps {
item: QortalMetadata; item: QortalMetadata;
index: number; index: number;
@ -474,13 +478,27 @@ export const ListItemWrapper: React.FC<ListItemWrapperProps> = ({
defaultLoaderParams, defaultLoaderParams,
renderListItemLoader, renderListItemLoader,
}) => { }) => {
const getResourceCache = useCacheStore((s)=> s.getResourceCache) const resourceKey = `${item.service}-${item.name}-${item.identifier}`;
const findCachedResource = getResourceCache( const entry = useCacheStore((s) => s.resourceCache[resourceKey]);
`${item.service}-${item.name}-${item.identifier}`, const [validResource, setValidResource] = useState(entry?.data ?? null);
true
); useEffect(() => {
if (findCachedResource === null && !renderListItemLoader) if (!entry) return setValidResource(null);
if (entry.expiry > Date.now()) {
setValidResource(entry.data);
} else {
useCacheStore.setState((s) => {
const newCache = { ...s.resourceCache };
delete newCache[resourceKey];
return { resourceCache: newCache };
});
setValidResource(null);
}
}, [entry, resourceKey]);
if (validResource === null && !renderListItemLoader)
return ( return (
<ItemCardWrapper height={60} isInCart={false}> <ItemCardWrapper height={60} isInCart={false}>
<ResourceLoader <ResourceLoader
@ -491,7 +509,7 @@ export const ListItemWrapper: React.FC<ListItemWrapperProps> = ({
/> />
</ItemCardWrapper> </ItemCardWrapper>
); );
if (findCachedResource === false && !renderListItemLoader) if (validResource === false && !renderListItemLoader)
return ( return (
<ItemCardWrapper height={60} isInCart={false}> <ItemCardWrapper height={60} isInCart={false}>
<ResourceLoader <ResourceLoader
@ -505,16 +523,16 @@ export const ListItemWrapper: React.FC<ListItemWrapperProps> = ({
); );
if ( if (
renderListItemLoader && renderListItemLoader &&
(findCachedResource === false || findCachedResource === null) (validResource === false || validResource === null)
) { ) {
return renderListItemLoader( return renderListItemLoader(
findCachedResource === null ? "LOADING" : "ERROR" validResource === null ? "LOADING" : "ERROR"
); );
} }
// Example transformation (Modify item if needed) // Example transformation (Modify item if needed)
const transformedItem = findCachedResource const transformedItem = validResource
? findCachedResource ? validResource
: { qortalMetadata: item, data: null }; : { qortalMetadata: item, data: null };
return <>{render(transformedItem, index)}</>; return <>{render(transformedItem, index)}</>;

View File

@ -23,7 +23,7 @@ interface VerticalPaginatedListProps {
defaultLoaderParams?: DefaultLoaderParams; defaultLoaderParams?: DefaultLoaderParams;
} }
export const VerticalPaginatedList = ({ const MemorizedComponent = ({
items, items,
listItem, listItem,
loaderItem, loaderItem,
@ -111,3 +111,5 @@ export const VerticalPaginatedList = ({
</> </>
); );
}; };
export const VerticalPaginatedList = React.memo(MemorizedComponent);