diff --git a/src/library-authoring/LibraryCollections.tsx b/src/library-authoring/LibraryCollections.tsx
index f35214ffec..e037277066 100644
--- a/src/library-authoring/LibraryCollections.tsx
+++ b/src/library-authoring/LibraryCollections.tsx
@@ -1,7 +1,6 @@
-import React, { useEffect } from 'react';
import { CardGrid } from '@openedx/paragon';
-import { useSearchContext } from '../search-manager';
+import { useLoadOnScroll, useSearchContext } from '../search-manager';
import { NoComponents, NoSearchResults } from './EmptyStates';
import CollectionCard from './components/CollectionCard';
import { LIBRARY_SECTION_PREVIEW_LIMIT } from './components/LibrarySection';
@@ -29,26 +28,12 @@ const LibraryCollections = ({ variant }: LibraryCollectionsProps) => {
const collectionList = variant === 'preview' ? collectionHits.slice(0, LIBRARY_SECTION_PREVIEW_LIMIT) : collectionHits;
- useEffect(() => {
- if (variant === 'full') {
- const onscroll = () => {
- // Verify the position of the scroll to implementa a infinite scroll.
- // Used `loadLimit` to fetch next page before reach the end of the screen.
- const loadLimit = 300;
- const scrolledTo = window.scrollY + window.innerHeight;
- const scrollDiff = document.body.scrollHeight - scrolledTo;
- const isNearToBottom = scrollDiff <= loadLimit;
- if (isNearToBottom && hasNextPage && !isFetchingNextPage) {
- fetchNextPage();
- }
- };
- window.addEventListener('scroll', onscroll);
- return () => {
- window.removeEventListener('scroll', onscroll);
- };
- }
- return () => {};
- }, [hasNextPage, isFetchingNextPage, fetchNextPage]);
+ useLoadOnScroll(
+ hasNextPage,
+ isFetchingNextPage,
+ fetchNextPage,
+ variant === 'full',
+ );
if (totalCollectionHits === 0) {
return isFiltered ? : ;
diff --git a/src/library-authoring/components/LibraryComponents.tsx b/src/library-authoring/components/LibraryComponents.tsx
index 4065826428..2aa3014b7e 100644
--- a/src/library-authoring/components/LibraryComponents.tsx
+++ b/src/library-authoring/components/LibraryComponents.tsx
@@ -1,7 +1,7 @@
-import React, { useEffect, useMemo } from 'react';
+import React, { useMemo } from 'react';
import { CardGrid } from '@openedx/paragon';
-import { useSearchContext } from '../../search-manager';
+import { useLoadOnScroll, useSearchContext } from '../../search-manager';
import { NoComponents, NoSearchResults } from '../EmptyStates';
import { useLibraryBlockTypes } from '../data/apiHooks';
import ComponentCard from './ComponentCard';
@@ -43,26 +43,12 @@ const LibraryComponents = ({ libraryId, variant }: LibraryComponentsProps) => {
return result;
}, [blockTypesData]);
- useEffect(() => {
- if (variant === 'full') {
- const onscroll = () => {
- // Verify the position of the scroll to implementa a infinite scroll.
- // Used `loadLimit` to fetch next page before reach the end of the screen.
- const loadLimit = 300;
- const scrolledTo = window.scrollY + window.innerHeight;
- const scrollDiff = document.body.scrollHeight - scrolledTo;
- const isNearToBottom = scrollDiff <= loadLimit;
- if (isNearToBottom && hasNextPage && !isFetchingNextPage) {
- fetchNextPage();
- }
- };
- window.addEventListener('scroll', onscroll);
- return () => {
- window.removeEventListener('scroll', onscroll);
- };
- }
- return () => {};
- }, [hasNextPage, isFetchingNextPage, fetchNextPage]);
+ useLoadOnScroll(
+ hasNextPage,
+ isFetchingNextPage,
+ fetchNextPage,
+ variant === 'full',
+ );
if (componentCount === 0) {
return isFiltered ? : ;
diff --git a/src/search-manager/SearchManager.ts b/src/search-manager/SearchManager.ts
index d1e925a91a..7b6992f3c3 100644
--- a/src/search-manager/SearchManager.ts
+++ b/src/search-manager/SearchManager.ts
@@ -184,3 +184,34 @@ export const useSearchContext = () => {
}
return ctx;
};
+
+/**
+ * Hook which loads next page of items on scroll
+ */
+export const useLoadOnScroll = (
+ hasNextPage: boolean | undefined,
+ isFetchingNextPage: boolean,
+ fetchNextPage: () => void,
+ enabled: boolean,
+) => {
+ React.useEffect(() => {
+ if (enabled) {
+ const onscroll = () => {
+ // Verify the position of the scroll to implementa a infinite scroll.
+ // Used `loadLimit` to fetch next page before reach the end of the screen.
+ const loadLimit = 300;
+ const scrolledTo = window.scrollY + window.innerHeight;
+ const scrollDiff = document.body.scrollHeight - scrolledTo;
+ const isNearToBottom = scrollDiff <= loadLimit;
+ if (isNearToBottom && hasNextPage && !isFetchingNextPage) {
+ fetchNextPage();
+ }
+ };
+ window.addEventListener('scroll', onscroll);
+ return () => {
+ window.removeEventListener('scroll', onscroll);
+ };
+ }
+ return () => {};
+ }, [hasNextPage, isFetchingNextPage, fetchNextPage]);
+};
diff --git a/src/search-manager/index.ts b/src/search-manager/index.ts
index 878bb14902..b06f9e193c 100644
--- a/src/search-manager/index.ts
+++ b/src/search-manager/index.ts
@@ -1,4 +1,4 @@
-export { SearchContextProvider, useSearchContext } from './SearchManager';
+export { SearchContextProvider, useLoadOnScroll, useSearchContext } from './SearchManager';
export { default as ClearFiltersButton } from './ClearFiltersButton';
export { default as FilterByBlockType } from './FilterByBlockType';
export { default as FilterByTags } from './FilterByTags';