reactjstypescripttanstackreact-query

How to avoid duplicating fallback in both API responses and useQuery in React Query?


In fetchOrgs, I'm already providing a fallback for items like so:

items: response.data ?? [].

But it seems like TypeScript still thinks data may still be undefined:

const orgs: Org[] | undefined

So this means I have to provide a fallback again:

const {
  data: { items: orgs = [] }, // In here...
} = useQuery({
  queryKey: ['orgs'],
  queryFn: () => fetchOrgs(),
});

const { totalItems: totalOrgs, totalFavs } = useTotal({
  fetchFn: fetchOrgs,
  prefix: 'org',
  items: orgs, // ...so that this is never undefined
});

How can I avoid defining the fallback twice (they are actually many)?

I could do this:

const {
  data,
} = useQuery({
  queryKey: ['orgs'],
  queryFn: () => fetchOrgs(),
});

if (!data) {
  return;
}

const {
  items: orgs,
} = data;

const { totalItems: totalOrgs, totalFavs } = useTotal({
  fetchFn: fetchOrgs,
  prefix: 'org',
  items: orgs,
});

But that would produce this error:

Rendered more hooks than during the previous render


Solution

  • The useQuery hook won't do this for you, but it's trivial to make a custom hook that you can use instead.

    function useOrgs() {
      const { data } = useQuery({
        queryKey: ["orgs"],
        queryFn: fetchOrgs,
      });
    
      return data?.items || [];
    }
    

    Now when you execute useOrgs() it always returns an array.

    This is probably also a good idea because it ties the query function to the query key, which can be easy to mess up in react query. And this gives you a place where you add custom logic around the query.

    See playground