React Query Cache Keys

· 381 words · 2 minute read

To make more advanced use of react-query requires mastering some strategies for cache management. One of the simplest is centralizing the generation of keys.

In the previous post about the custom hooks with React Query, we analyzed the following example:

export function useQueryActiveUsers({
  countries,
  disabled,
}: {
  countries: string[];
  disabled?: boolean;
}): {
  users?: UsersResponse[];
  isLoading: boolean;
} {
  const { addToast } = useToast();

  const { data, error, isLoading } = useQuery<UsersResponse[], Error>(
    [CACHE_KEY.users({ countries })],
    API.users.get({ countries }),
    {
      enabled: !disabled && !!countries.length,
      staleTime: 1 * 60 * 60 * 1000,
    }
  );

  useEffect(() => {
    if (!error || !addToast) {
      return;
    }

    addErrorToast("Error retrieving users");
  }, [error, addToast]);

  const users = data.users.filter((user) => user.active);

  return { users, isLoading };
}

This time, we’ll focus on this snippet of code:

const { data, error, isLoading } = useQuery<UsersResponse[], Error>(
  [CACHE_KEY.users({ countries })],
  API.users.get({ countries }),
  {
    enabled: !disabled && !!countries.length,
    staleTime: 1 * 60 * 60 * 1000,
  }
);

Specifically, on this line:

[CACHE_KEY.users({ countries })],

The first parameter of the useQuery function is the key that will be used to store the data returned by the server call.

In most common projects, we won’t need to worry too much about these values, we just need to set them, and React Query will handle its part of the job. However, some applications require more manual management of cache data. For example, we might store the values of a list and set the individual details of each element in the cache, so that when we want to retrieve the detail, and if we have listed all the elements before, we can retrieve the individual value from the cache.

To better manage the cache, a recommended strategy is to create a file that serves as a ‘generator’ of cache keys. These cache keys will also depend on the parameters of the call, so they won’t be strings but functions.

Create a file similar to cache-keys.ts:

function getUsersCacheKey({ countries }: { coutries: string[] }) {
  return ["users", countries];
}

export const CACHE_KEY = {
  users: getUsersCacheKey,
};

Exactly, the functions will be different depending on the number of parameters of each call, which we must take into account to avoid errors where the cache is incorrectly resolved when it shouldn’t be.