UNPKG

react-firehooks

Version:

Lightweight dependency-free collection of React hooks for Firebase

53 lines (52 loc) 2.31 kB
import { useEffect, useMemo, useRef } from "react"; import { useIsMounted } from "./useIsMounted.js"; import { useMultiLoadingValue } from "./useMultiLoadingValue.js"; /** * @internal */ export function useMultiGet(references, getData, isEqual) { const isMounted = useIsMounted(); const { states, setError, setLoading, setValue } = useMultiLoadingValue(references.length); const prevReferences = useRef([]); const ongoingFetchReferences = useRef([]); useEffect(() => { // shorten `prevReferences` size if number of references was reduced prevReferences.current = prevReferences.current.slice(0, references.length); // shorten `ongoingFetchReferences` size if number of references was reduced ongoingFetchReferences.current = ongoingFetchReferences.current.slice(0, references.length); // fetch to new references const changedReferences = references .map((ref, refIndex) => [ref, refIndex]) .filter(([ref, refIndex]) => !isEqual(ref, prevReferences.current[refIndex])); for (const [ref, refIndex] of changedReferences) { prevReferences.current[refIndex] = ref; setLoading(refIndex); ongoingFetchReferences.current[refIndex] = ref; (async () => { try { const data = await getData(ref); if (!isMounted.current) { return; } if (!isEqual(ongoingFetchReferences.current[refIndex], ref)) { return; } setValue(refIndex, data); } catch (e) { if (!isMounted.current) { return; } if (!isEqual(ongoingFetchReferences.current[refIndex], ref)) { return; } // We assume this is always a Error setError(refIndex, e); } })(); } // TODO: double check dependencies // eslint-disable-next-line react-hooks/exhaustive-deps }, [references]); return useMemo(() => states.map((state) => [state.value, state.loading, state.error]), [states]); }