Skip to content

Commit b2c00e3

Browse files
committed
refactor: move load on scroll logic to custom hook
1 parent 32fd132 commit b2c00e3

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

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)