3

I'm using react-query 3.30 in an Ionic React app.

I have a paged query:

export function useCardAdmin(
  currentJsonUrl: string,
): UseQueryResult<JsonDataWidgetPagerRead, Error> {
  const query = currentJsonUrl;
  const queryKey = queryKeyUseWidgetAdmin(currentJsonUrl);
  return useQuery<JsonDataWidgetPagerRead, Error>(
    queryKey,
    async () => fetchAuth(query, true),
    {
      keepPreviousData: true,
      staleTime: DAY_MILLISECONDS,
      cacheTime: DAY_MILLISECONDS,
    },
  );
}

export const queryKeyUseWidgetAdmin = (currentJsonUrl: string): string => (`getWidgetAdmin${currentJsonUrl}`);

This is working fine.

A typical query key value is getCardsAdminhttps://example.com/jsonapi/widgets?&fields[widget]=id,drupalId,part,gadget,refGroup&filter[uid.id][value]=adadfasf-f992-489c-9519-038f1728e0db&sort=-created&page[limit]=25

However, when a user updates a widget (PATCH to server), then I need to invalidate the query.

So I tried this:

queryClient.invalidateQueries('getWidgetAdmin')

I expected all queries that begin with getWidgetAdmin to be invalidated because the documentation says that the argument to invalidateQueries is treated as a prefix. However, none of them are invalidated.

If I use the exact query key, like this:

queryClient.invalidateQueries(queryKeyUseWidgetAdmin(currentJsonUrl))

then the query is invalidated. But I want to invalidate all the queries that begin with getWidgetAdmin, not just one of them.

I also tried setting exact:

queryClient.invalidateQueries('getWidgetAdmin', { exact: false })

This didn't work, either.

How can I invalidate a group of queries in react-query?

Additional info:

I was initializing QueryClient() with some custom config, but even when I initialize queryClient without any config (const queryClient = new QueryClient();), I still get the same problem.

1 Answer 1

4

The fuzzy query key matching only works for Arrays. So if your key is:

['getWidgetAdmin', some, more, filters]

You can fuzzily invalidate with:

queryClient.invalidateQueries(['getWidgetAdmin'])

if it really needs to be a string startsWith, you can supply a predicate function (see the QueryFilters documentation):

queryClient.invalidateQueries({
predicate: (query) => query.queryKey.startsWith('getWidgetAdmin')})
Sign up to request clarification or add additional context in comments.

3 Comments

Wow, I thought the key had to be a string; using arrays makes much more sense, and switching to array keys instantly solved my problem and opened up several possibilities for my app. Many thanks!
@TkDodo Would it be possible to invalidate ['getWidgetAdmin', 'some', more, filters] with queryClient.invalidateQueries(['some']) ?
It is if you use objects instead of arrays. Arrays have an order. See: tkdodo.eu/blog/…

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.