Last active
June 29, 2022 05:24
-
-
Save chnirt/0e1aefeddaa1dde05af77605f55621dc to your computer and use it in GitHub Desktop.
useFetch for firebase with fetch and load more
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import { useCallback, useEffect, useState } from 'react' | |
import { | |
collection, | |
query, | |
orderBy, | |
limit, | |
startAfter, | |
onSnapshot, | |
} from 'firebase/firestore' | |
import { db } from '../../firebase' | |
export const useFetch = (collectionName = 'todos', LIMIT = 10) => { | |
const [loading, setLoading] = useState(false) | |
const [data, setData] = useState([]) | |
const [last, setLast] = useState(null) | |
const [moreLoading, setMoreLoading] = useState(false) | |
const [loadedAll, setLoadedAll] = useState(false) | |
const fetchData = useCallback(async () => { | |
const limitNumber = LIMIT + 1 | |
// Query the first page of docs | |
const first = query( | |
collection(db, collectionName), | |
orderBy('createdAt', 'desc'), | |
limit(limitNumber) | |
) | |
onSnapshot(first, (querySnapshot) => { | |
const docs = querySnapshot.docs.slice(0, LIMIT) | |
const data = docs.map((docSnapshot) => { | |
return { | |
id: docSnapshot.id, | |
...docSnapshot.data(), | |
} | |
}) | |
setData(data) | |
const lastVisible = docs[docs.length - 1] | |
setLast(lastVisible) | |
const size = querySnapshot.size | |
setLoadedAll(size < limitNumber) | |
}) | |
}, []) | |
const fetchMoreData = useCallback(async () => { | |
const limitNumber = LIMIT + 1 | |
const next = query( | |
collection(db, collectionName), | |
orderBy('createdAt', 'desc'), | |
limit(limitNumber), | |
startAfter(last) | |
) | |
onSnapshot(next, (querySnapshot) => { | |
const docs = querySnapshot.docs.slice(0, LIMIT) | |
const data = docs.map((docSnapshot) => { | |
return { | |
id: docSnapshot.id, | |
...docSnapshot.data(), | |
} | |
}) | |
setData((prevState) => [...prevState, ...data]) | |
const lastVisible = docs[docs.length - 1] | |
setLast(lastVisible) | |
const size = querySnapshot.size | |
setLoadedAll(size < limitNumber) | |
}) | |
}, [last]) | |
const handleLoadMore = useCallback(() => { | |
setMoreLoading(true) | |
fetchMoreData().finally(() => { | |
setMoreLoading(false) | |
}) | |
}, [fetchMoreData]) | |
useEffect(() => { | |
setLoading(true) | |
fetchData().finally(() => { | |
setLoading(false) | |
}) | |
}, [fetchData]) | |
return { | |
loading, | |
data, | |
moreLoading, | |
loadedAll, | |
handleLoadMore | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment