Files
aso/frontend/dashboard/src/hooks/useLoadOnScroll.ts
2023-10-31 18:29:05 +07:00

99 lines
2.4 KiB
TypeScript

import { RefObject, useEffect, useRef, useState } from 'react';
interface FetchFunction<T> {
(page: number): Promise<T[]>;
}
const useLoadOnScroll = <T>(executeFetch: FetchFunction<T>) => {
const [data, setData] = useState<T[]>([]);
const [isLoading, setIsLoading] = useState<boolean>(false);
const [page, setPage] = useState<number>(1);
const [listener, setListener] = useState<number>(1);
const [lastPage, setLastPage] = useState<boolean>(false);
const fetchData = async (isSearch?: boolean) => {
if (!lastPage || isSearch === true)
if (isLoading === false) {
setIsLoading(true);
if (isSearch === true) {
const newData = await executeFetch(1);
if (newData.length > 0) {
setData(newData);
setPage((prevPage) => 2);
} else {
setLastPage(true);
setData([]);
}
} else {
const newData = await executeFetch(page);
if (newData.length > 0) {
setData((prevData) => [...prevData, ...newData]);
setPage((prevPage) => prevPage + 1);
} else {
setLastPage(true);
}
}
setIsLoading(false);
}
};
const refetchData = () => {
setPage(1);
setListener((prev) => prev + 1);
};
const resetLastPage = () => {
setLastPage(false);
};
useEffect(() => {
fetchData();
}, [listener]);
// useEffect(() => {
// if (data.length === 0) {
// fetchData();
// }
// }, [data]);
const handleScroll = () => {
const { scrollTop, clientHeight, scrollHeight } = document.documentElement;
if (scrollTop + clientHeight >= scrollHeight - 1) {
setListener((prevListener) => prevListener + 1);
}
};
const resetSearch = () => {
console.log('reset search');
fetchData(true);
resetLastPage();
};
useEffect(() => {
window.addEventListener('scroll', handleScroll);
return () => {
window.removeEventListener('scroll', handleScroll);
};
}, []);
const onClose = () => {
setData([]);
setPage(1);
setLastPage(false);
};
const onOpen = () => {
setData([]);
setLastPage(false);
fetchData(true);
};
// setData and setPage to reset when the dialog closed
return { data, isLoading, setPage, setData, resetSearch, resetLastPage, onClose, onOpen, refetchData };
};
export default useLoadOnScroll;