74 lines
2.1 KiB
JavaScript
74 lines
2.1 KiB
JavaScript
import { useState, useEffect } from "react";
|
|
|
|
export const useFirestorePagination = ({
|
|
ref = null,
|
|
refreshArray = [],
|
|
condition = false,
|
|
documentID = "id",
|
|
batchSize = 10,
|
|
maxLoads = 15, // Maximum number of times loadMore can be called
|
|
}) => {
|
|
const [data, setData] = useState([]);
|
|
const [loading, setLoading] = useState(false);
|
|
const [lastVisible, setLastVisible] = useState(null);
|
|
const [error, setError] = useState(null);
|
|
const [loadMoreCount, setLoadMoreCount] = useState(0); // Counter for loadMore invocations
|
|
|
|
useEffect(() => {
|
|
let unsubscribe = () => {};
|
|
|
|
if (condition && ref) {
|
|
setLoading(true);
|
|
unsubscribe = ref.limit(batchSize).onSnapshot(
|
|
(snapshot) => {
|
|
const fetchedDocuments = snapshot.docs.map((doc) => ({
|
|
[documentID]: doc.id,
|
|
...doc.data(),
|
|
}));
|
|
const lastVisibleDocument = snapshot.docs[snapshot.docs.length - 1];
|
|
setData(fetchedDocuments);
|
|
setLastVisible(lastVisibleDocument);
|
|
setLoading(false);
|
|
},
|
|
(err) => {
|
|
setError(err);
|
|
setLoading(false);
|
|
}
|
|
);
|
|
}
|
|
|
|
return () => unsubscribe();
|
|
}, [...refreshArray, condition, ref, batchSize]);
|
|
|
|
const loadMore = () => {
|
|
if (lastVisible && !loading && loadMoreCount < maxLoads) {
|
|
setLoading(true);
|
|
setLoadMoreCount((count) => count + 1); // Increment loadMore counter
|
|
|
|
ref
|
|
.startAfter(lastVisible)
|
|
.limit(batchSize)
|
|
.onSnapshot(
|
|
(snapshot) => {
|
|
const newDocuments = snapshot.docs.map((doc) => ({
|
|
[documentID]: doc.id,
|
|
...doc.data(),
|
|
}));
|
|
setData((prev) => [...prev, ...newDocuments]);
|
|
setLastVisible(snapshot.docs[snapshot.docs.length - 1]);
|
|
setLoading(false);
|
|
},
|
|
(err) => {
|
|
setError(err);
|
|
setLoading(false);
|
|
}
|
|
);
|
|
}
|
|
};
|
|
|
|
// Function to check if more data can be loaded
|
|
const canLoadMore = loadMoreCount < maxLoads;
|
|
|
|
return { data, loading, error, loadMore, canLoadMore };
|
|
};
|