UNPKG

react-firehooks

Version:

Lightweight dependency-free collection of React hooks for Firebase

36 lines (35 loc) 1.92 kB
import { useEffect, useMemo, useRef } from "react"; import { useMultiLoadingValue } from "./useMultiLoadingValue.js"; /** * @internal */ export function useMultiListen(references, onChange, isEqualRef) { const { states, setError, setLoading, setValue } = useMultiLoadingValue(references.length); const prevReferences = useRef([]); const subscriptions = useRef([]); useEffect(() => { var _a, _b; // unsubscribe and shorten `subscriptions` if number of references was reduced subscriptions.current.slice(references.length).forEach((unsubscribe) => unsubscribe()); subscriptions.current = subscriptions.current.slice(0, references.length); // shorten `prevReferences` size if number of references was reduced prevReferences.current = prevReferences.current.slice(0, references.length); // subscribe to new references and unsubscribe to changed references const changedReferences = references .map((ref, refIndex) => [ref, refIndex]) .filter(([ref, refIndex]) => !isEqualRef(ref, prevReferences.current[refIndex])); for (const [ref, refIndex] of changedReferences) { (_b = (_a = subscriptions.current)[refIndex]) === null || _b === void 0 ? void 0 : _b.call(_a); prevReferences.current[refIndex] = ref; setLoading(refIndex); subscriptions.current[refIndex] = onChange(ref, (snap) => setValue(refIndex, snap), (error) => setError(refIndex, error)); } }, [references, isEqualRef, onChange, setError, setLoading, setValue]); // unsubscribe and cleanup on unmount useEffect(() => () => { subscriptions.current.forEach((unsubscribe) => unsubscribe()); subscriptions.current = []; prevReferences.current = []; }, []); return useMemo(() => states.map((state) => [state.value, state.loading, state.error]), [states]); }