Press n or j to go to the next uncovered block, b, p or k for the previous block.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 | 12x 12x 12x 12x 12x 12x 26x 652x 652x 652x 103x 5x 18x 652x 101x 652x 652x 2x 2x 652x 702x 699x 80x 652x 699x 699x 691x 682x 658x 652x 652x 535x 652x 626x 626x 626x | import { useQueries, useQueryClient } from "@tanstack/react-query"; import { userKey } from "features/queryKeys"; import { userStaleTime } from "features/userQueries/constants"; import { useCallback, useEffect, useRef } from "react"; import { service } from "service"; import { arrayEq } from "utils/arrayEq"; export default function useUsers( ids: (number | undefined)[], invalidate = false, ) { const queryClient = useQueryClient(); const idsRef = useRef(ids); const handleInvalidation = useCallback(() => { if (invalidate) { queryClient.invalidateQueries({ predicate: (query) => query.queryKey[0] === userKey()[0] && !!idsRef.current.includes(query.queryKey[1] as number), // tells v5 to immediately refetch active observers after invalidation refetchType: "active", }); } }, [invalidate, queryClient]); useEffect(() => { handleInvalidation(); }, [handleInvalidation]); //arrays use reference equality, so you can't use ids in useEffect directly useEffect(() => { if (!arrayEq(idsRef.current, ids)) { idsRef.current = ids; handleInvalidation(); } }); const queries = useQueries({ queries: ids .filter((id): id is number => !!id) .map((id) => ({ queryFn: () => service.user.getUser(id.toString()), queryKey: userKey(id), staleTime: userStaleTime, })), }); const errors = queries .map((query) => query.error && typeof (query.error as Error).message === "string" ? (query.error as Error).message : undefined, ) .filter((e): e is string => typeof e === "string"); const isPending = queries.some((query) => query.isPending); const isFetching = queries.some((query) => query.isFetching); // If at least one user query is not loading (i.e. has data loaded before), whilst // some other (likely new) queries are fetching, then it's a refetch const isRefetching = !queries.every((query) => query.isLoading) && isFetching; const isError = !!errors.length; const usersById = isPending ? undefined : new Map(queries.map((q, index) => [ids[index], q.data])); return { data: usersById, errors, isError, isFetching, isLoading: isPending, isRefetching, }; } export function useUser(id: number | undefined, invalidate = false) { const result = useUsers([id], invalidate); return { data: result.data?.get(id), error: result.errors.join("\n"), isError: result.isError, isFetching: result.isFetching, isLoading: result.isLoading, }; } |