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 651x 651x 651x 95x 5x 18x 651x 93x 651x 651x 2x 2x 651x 701x 698x 70x 651x 698x 698x 690x 681x 657x 651x 651x 534x 651x 625x 625x 625x | 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, }; } |