Skip to content

Commit 12767d9

Browse files
committed
refactor: move load on scroll logic to custom hook
1 parent 4ef64a8 commit 12767d9

File tree

4 files changed

+47
-45
lines changed

4 files changed

+47
-45
lines changed

src/library-authoring/LibraryCollections.tsx

Lines changed: 7 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,6 @@
1-
import React, { useEffect } from 'react';
21
import { CardGrid } from '@openedx/paragon';
32

4-
import { useSearchContext } from '../search-manager';
3+
import { useLoadOnScroll, useSearchContext } from '../search-manager';
54
import { NoComponents, NoSearchResults } from './EmptyStates';
65
import CollectionCard from './components/CollectionCard';
76
import { LIBRARY_SECTION_PREVIEW_LIMIT } from './components/LibrarySection';
@@ -29,26 +28,12 @@ const LibraryCollections = ({ variant }: LibraryCollectionsProps) => {
2928

3029
const collectionList = variant === 'preview' ? collectionHits.slice(0, LIBRARY_SECTION_PREVIEW_LIMIT) : collectionHits;
3130

32-
useEffect(() => {
33-
if (variant === 'full') {
34-
const onscroll = () => {
35-
// Verify the position of the scroll to implementa a infinite scroll.
36-
// Used `loadLimit` to fetch next page before reach the end of the screen.
37-
const loadLimit = 300;
38-
const scrolledTo = window.scrollY + window.innerHeight;
39-
const scrollDiff = document.body.scrollHeight - scrolledTo;
40-
const isNearToBottom = scrollDiff <= loadLimit;
41-
if (isNearToBottom && hasNextPage && !isFetchingNextPage) {
42-
fetchNextPage();
43-
}
44-
};
45-
window.addEventListener('scroll', onscroll);
46-
return () => {
47-
window.removeEventListener('scroll', onscroll);
48-
};
49-
}
50-
return () => {};
51-
}, [hasNextPage, isFetchingNextPage, fetchNextPage]);
31+
useLoadOnScroll(
32+
hasNextPage,
33+
isFetchingNextPage,
34+
fetchNextPage,
35+
variant === 'full',
36+
);
5237

5338
if (totalCollectionHits === 0) {
5439
return isFiltered ? <NoSearchResults searchType="collection" /> : <NoComponents searchType="collection" />;

src/library-authoring/components/LibraryComponents.tsx

Lines changed: 8 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
1-
import React, { useEffect, useMemo } from 'react';
1+
import React, { useMemo } from 'react';
22
import { CardGrid } from '@openedx/paragon';
33

4-
import { useSearchContext } from '../../search-manager';
4+
import { useLoadOnScroll, useSearchContext } from '../../search-manager';
55
import { NoComponents, NoSearchResults } from '../EmptyStates';
66
import { useLibraryBlockTypes } from '../data/apiHooks';
77
import ComponentCard from './ComponentCard';
@@ -43,26 +43,12 @@ const LibraryComponents = ({ libraryId, variant }: LibraryComponentsProps) => {
4343
return result;
4444
}, [blockTypesData]);
4545

46-
useEffect(() => {
47-
if (variant === 'full') {
48-
const onscroll = () => {
49-
// Verify the position of the scroll to implementa a infinite scroll.
50-
// Used `loadLimit` to fetch next page before reach the end of the screen.
51-
const loadLimit = 300;
52-
const scrolledTo = window.scrollY + window.innerHeight;
53-
const scrollDiff = document.body.scrollHeight - scrolledTo;
54-
const isNearToBottom = scrollDiff <= loadLimit;
55-
if (isNearToBottom && hasNextPage && !isFetchingNextPage) {
56-
fetchNextPage();
57-
}
58-
};
59-
window.addEventListener('scroll', onscroll);
60-
return () => {
61-
window.removeEventListener('scroll', onscroll);
62-
};
63-
}
64-
return () => {};
65-
}, [hasNextPage, isFetchingNextPage, fetchNextPage]);
46+
useLoadOnScroll(
47+
hasNextPage,
48+
isFetchingNextPage,
49+
fetchNextPage,
50+
variant === 'full',
51+
);
6652

6753
if (componentCount === 0) {
6854
return isFiltered ? <NoSearchResults /> : <NoComponents />;

src/search-manager/SearchManager.ts

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -185,3 +185,34 @@ export const useSearchContext = () => {
185185
}
186186
return ctx;
187187
};
188+
189+
/**
190+
* Hook which loads next page of items on scroll
191+
*/
192+
export const useLoadOnScroll = (
193+
hasNextPage: boolean | undefined,
194+
isFetchingNextPage: boolean,
195+
fetchNextPage: () => void,
196+
enabled: boolean,
197+
) => {
198+
React.useEffect(() => {
199+
if (enabled) {
200+
const onscroll = () => {
201+
// Verify the position of the scroll to implementa a infinite scroll.
202+
// Used `loadLimit` to fetch next page before reach the end of the screen.
203+
const loadLimit = 300;
204+
const scrolledTo = window.scrollY + window.innerHeight;
205+
const scrollDiff = document.body.scrollHeight - scrolledTo;
206+
const isNearToBottom = scrollDiff <= loadLimit;
207+
if (isNearToBottom && hasNextPage && !isFetchingNextPage) {
208+
fetchNextPage();
209+
}
210+
};
211+
window.addEventListener('scroll', onscroll);
212+
return () => {
213+
window.removeEventListener('scroll', onscroll);
214+
};
215+
}
216+
return () => {};
217+
}, [hasNextPage, isFetchingNextPage, fetchNextPage]);
218+
};

src/search-manager/index.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
export { SearchContextProvider, useSearchContext } from './SearchManager';
1+
export { SearchContextProvider, useLoadOnScroll, useSearchContext } from './SearchManager';
22
export { default as ClearFiltersButton } from './ClearFiltersButton';
33
export { default as FilterByBlockType } from './FilterByBlockType';
44
export { default as FilterByTags } from './FilterByTags';

0 commit comments

Comments
 (0)